通常TableView設置全屏分隔線有下面三種方法git
首先先隱藏系統自帶的分割線, 接下來有2種作法 (建議使用作法a) tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
或者 self.tableView.separatorColor = [UIColor clearColor];
github
作法a: 能夠經過addSubview的方式添加一條分割線bash
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
//自定義分割線方法一: 經過addSubview的方式添加一條分割線
//在自定義cell 裏面給每一個cell添加高度爲2的紅色分割線
CGFloat cellH = cell.frame.size.height;
if(indexPath.row != cars.count - 1){
UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, cellH-2, self.view.frame.size.width, 2)];
line.backgroundColor = [UIColor redColor];
[cell addSubview:line];
}
return cell;
}
複製代碼
// 自繪分割線
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextFillRect(context, rect);
CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
//繪製高度爲2綠色分割線
CGContextStrokeRect(context, CGRectMake(0, rect.size.height - 2, rect.size.width, 2));
}
複製代碼
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// 設置tableView背景色
self.tableView.backgroundColor = [UIColor colorWithWhite:215 / 255.0 alpha:1];
複製代碼
- (void)setFrame:(CGRect)frame
{
frame.size.height -= 1;
// 給cellframe賦值
[super setFrame:frame];
}
複製代碼
-(void)viewDidLoad {
[super viewDidLoad];
//1.調整(iOS7以上)表格分隔線邊距
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
self.tableView.separatorInset = UIEdgeInsetsZero;
}
//2.調整(iOS8以上)view邊距(或者在cell中設置preservesSuperviewLayoutMargins,兩者等效)
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
self.tableView.layoutMargins = UIEdgeInsetsZero;
}
}
複製代碼
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];
//2.調整(iOS8以上)tableView邊距(與上面第2步等效,二選一便可)
if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
cell.preservesSuperviewLayoutMargins = NO;
}
//3.調整(iOS8以上)view邊距
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
return cell;
}
複製代碼
方法1 中作法a比較好用,能夠使用系統自帶的cell, 可是須要添加一個view,設置背景顏色和frame. 而作法b僅僅爲了分隔線卻還必須再自定義cell, 重寫drawRect,又顯得麻煩;ide
方法2比較取巧,可是也須要自定義cell,在某些狀況下不容許改變tableView的背景色,使用場景有限;佈局
方法3不須要自定義cell,對系統(iOS7,iOS8以上)作個簡單判斷便可.惋惜網上不少文章寫的不對,不少人不會正確使用,有些會用的人也說不清楚原理,只管複製粘貼. 好比網上流傳的通常是這樣,須要四步,雖然真的管用,但多了一步[cell setSeparatorInset:UIEdgeInsetsZero];
並且原理也沒講,估計是某大神寫的,根本不屑於過多解釋,讓我用起來很鬱悶,網上流傳代碼:ui
首先在viewDidLoad方法中加上以下代碼:
-(void)viewDidLoad {
[super viewDidLoad];
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
而後在willDisplayCell方法中加入以下代碼:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
複製代碼
其實關於分隔線不能全屏的原理,蘋果官方在文件中已經說明了,能夠去看一下atom
在iOS7以前系統默認就是全屏的,iOS7時UITableView
多了separatorInset
屬性,可在UITableView
的頭文件中查看,以下:spa
@property (nonatomic) UIEdgeInsets separatorInset NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
// allows customization of the frame of cell separators
複製代碼
iOS7時只要設置該屬性爲UIEdgeInsetsZero
就沒有問題了.code
iOS8以後僅僅完成以上設置就不行了,仔細查看後發現iOS8的UIView
的頭文件裏又多了個layoutMargins
屬性,並有官方註釋cdn
@property (nonatomic) UIEdgeInsets layoutMargins NS_AVAILABLE_IOS(8_0);
複製代碼
/*
-layoutMargins returns a set of insets from the edge of the view's bounds that denote a default spacing for laying out content. If preservesSuperviewLayoutMargins is YES, margins cascade down the view tree, adjusting for geometry offsets, so that setting the left value of layoutMargins on a superview will affect the left value of layoutMargins for subviews positioned close to the left edge of their superview's bounds
If your view subclass uses layoutMargins in its layout or drawing, override -layoutMarginsDidChange in order to refresh your view if the margins change.
*/
大意是說:layoutMargins是view的bounds的邊距,用來調整內容默認邊距
若是preservesSuperviewLayoutMargins屬性是YES,那麼設置父控件的layoutMargins邊距,
就會影響全部子控件的相對於父控件bounds的layoutMargins邊距
若是你的view的子類在佈局或者繪圖中使用了layoutMargins屬性,須要重寫-layoutMarginsDidChange 方法,
以便當邊距改變時能刷新你的view
複製代碼
正是由於layoutMargins是UIView的新增屬性,tablet和cell做爲UIView的子類都有這個屬性,因此相比較iOS7系統,iOS8以後就多了兩步,必須同時再對tableView和cell的layoutMargins屬性進行處理,才能讓分隔線真正全屏.
同時官方註釋中對preservesSuperviewLayoutMargins(意即:維持父控件的佈局邊距)屬性的說明,也正好能說明網上另外一種方法不設置self.tableView.layoutMargins = UIEdgeInsetsZero;
而是設置cell.preservesSuperviewLayoutMargins = NO;
爲何也能起做用
弄清楚了這些原理,就能夠更好的記憶和使用這些方法,不用每次都去舊代碼查找或者去百度了.
說到了最後,不知道你們有沒有以爲影響分隔線全屏的元兇layoutMargins屬性 稍微有點眼熟呢?其實它在另外一個地方也作了很多惡,就在storyboard中:
PS:附效果圖以下:
設置以前效果圖:
設置完第1步self.tableView.separatorInset = UIEdgeInsetsZero;
後效果圖:
設置完第2步self.tableView.layoutMargins = UIEdgeInsetsZero;
後效果圖:
設置完第3步cell.layoutMargins = UIEdgeInsetsZero;
後效果圖:
因爲筆者水平有限,文中若是有錯誤的地方,或者有更好的方法,還望大神指出。 附上本文的全部 demo 下載連接,【GitHub】。 若是你看完後以爲對你有所幫助,還望在 GitHub 上點個 star。贈人玫瑰,手有餘香。