一、問題描述
UITableView分割線要顯示到最左端

查看UITableView的屬性,發現設置separatorInset的值可以自定義分割線的位置。
@property (nonatomic) UIEdgeInsets separatorInset NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; // allows customization of the frame of cell separators
打印separatorInset,其默認值{0, 15, 0, 0},上、左、下、右距離原位置分別為0、15、0、0,即左側會有默認15像素的空白
全局設置每個cell的separatorInset值。在UITableViewController的-(void)viewDidLoad方法中設置UITableView分割線,UIEdgeInsetsZero相當於UIEdgeInsetsMake(0, 0, 0, 0)。
1 -(void)viewDidLoad 2 { 3 //設置分割線距邊界的距離 4 //在iOS7之前沒有separatorInset,運行會導致程序崩潰,所以要加下判斷 5 //if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 6 //{ 7 // self.tableView.separatorInset = UIEdgeInsetsZero; 8 //} 9 if([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) 10 { 11 self.tableView.separatorInset = UIEdgeInsetsZero; 12 } 13 }
或者單獨每個cell的separatorInset值。在UITableViewController的-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath方法中設置UITableView分割線,UIEdgeInsetsZero相當於UIEdgeInsetsMake(0, 0, 0, 0)。
1 -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3 //設置分割線距邊界的距離 4 //在iOS7之前沒有separatorInset,運行會導致程序崩潰,所以要加下判斷 5 //if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 6 //{ 7 // cell.separatorInset = UIEdgeInsetsZero; 8 //} 9 if ([cell respondsToSelector:@selector(setSeparatorInset:)]){ 10 cell.separatorInset = UIEdgeInsetsZero; 11 } 12 }
運行,發現達不到我想要的效果,分割線只是距離最左端近了,但還是沒顯示到最左端,效果圖如下:

二、問題分析
iOS7,想要設置cell的分割線顯示到最左端,只需要設置separatorInset的值為UIEdgeInsetsZero。
iOS8,簡單設置separatorInset的值為UIEdgeInsetsZero的方法已經無效了。UIView的layoutMargins 默認為{8, 8, 8, 8}。
cell的preservesSuperviewLayoutMargins默認為true時,可能會導致cell被其父UITableView的LayoutMargin影響。如果設置為false時,cell不被UITableView的LayoutMargin影響。
三、問題解決
1.方法一:
全局設置cell的separatorInset的值為UIEdgeInsetsZero,UITableView的layoutMargins設置為UIEdgeInsetsZero,並且cell的layoutMargins設置為UIEdgeInsetsZero。
1 -(void)viewDidLoad 2 { 3 //設置分割線距邊界的距離 4 //在iOS7之前沒有separatorInset,運行會導致程序崩潰,所以要加下判斷 5 //if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 6 //{ 7 // self.tableView.separatorInset = UIEdgeInsetsZero; 8 //} 9 if([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) 10 { 11 self.tableView.separatorInset = UIEdgeInsetsZero; 12 } 13 if([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) 14 { 15 self.tableView.layoutMargins = UIEdgeInsetsZero; 16 } 17 }
1 -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3 if ([cell respondsToSelector:@selector(setLayoutMargins:)]) { 4 cell.layoutMargins = UIEdgeInsetsZero; 5 } 6 }
2.方法二:
preservesSuperviewLayoutMargins默認為true,cell被UITableView的layoutMargins影響。
設置cell的separatorInset值為UIEdgeInsetsZero,cell的layoutMargins值為UIEdgeInsetsZero,並且cell的preservesSuperviewLayoutMargins為false時,避免cell被UITableView的layoutMargins影響。
1 -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3 if ([cell respondsToSelector:@selector(setSeparatorInset:)]){ 4 cell.separatorInset = UIEdgeInsetsZero; 5 } 6 if ([cell respondsToSelector:@selector(setLayoutMargins:)]) { 7 cell.layoutMargins = UIEdgeInsetsZero; 8 } 9 //preservesSuperviewLayoutMargins設置為false時,子view不被其父view的LayoutMargin影響 10 if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) { 11 cell.preservesSuperviewLayoutMargins = false; 12 } 13 }
最終效果:

四、存在問題
該方法設置cell的分割線,在豎屏下顯示正常,在橫屏下會無效。網上查閱,發現解決cell分割線的方法都存在着這個問題

五、飲水思源
1.http://stackoverflow.com/questions/25770119/ios-8-uitableview-separator-inset-0-not-working
2.http://dev.classmethod.jp/smartphone/iphone/ios-8-uitableview-layoutmargins/
3.http://www.cnblogs.com/Alex-798-Dcr/p/5279920.html
4.http://www.skyfox.org/ios7-tableview-separatorinset-ajust.html
