iOS利用UITableView設(shè)置全屏分隔線的3種方法總結(jié)
前言
本文主要給大家總結(jié)了iOS用UITableView設(shè)置全屏分隔線的3種方法,一般TableView設(shè)置全屏分隔線有下面三種方法:
1.自定義cell,手動(dòng)添加分割線
隱藏自帶的
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
可以通過(guò)addSubview的方式添加一條分割線;也可以自繪分割線。
// 自繪分割線 - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextFillRect(context, rect); CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0xE2/255.0f green:0xE2/255.0f blue:0xE2/255.0f alpha:1].CGColor); CGContextStrokeRect(context, CGRectMake(0, rect.size.height - 1, rect.size.width, 1)); }
2.重寫(xiě)cell的setFrame方法,高度-1,露出背景色
- (void)setFrame:(CGRect)frame { frame.size.height -= 1; // 給cellframe賦值 [super setFrame:frame]; }
取消系統(tǒng)的分割線
設(shè)置tableView背景色為分割線顏色
// 取消系統(tǒng)分割線 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // 設(shè)置tableView背景色 self.tableView.backgroundColor = [UIColor colorWithWhite:215 / 255.0 alpha:1];
3.利用系統(tǒng)屬性設(shè)置(separatorInset, layoutMargins)共需添加三句代碼:
對(duì)tableView的separatorInset, layoutMargins屬性的設(shè)置
-(void)viewDidLoad { [super viewDidLoad]; //1.調(diào)整(iOS7以上)表格分隔線邊距 if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) { self.tableView.separatorInset = UIEdgeInsetsZero; } //2.調(diào)整(iOS8以上)view邊距(或者在cell中設(shè)置preservesSuperviewLayoutMargins,二者等效) if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) { self.tableView.layoutMargins = UIEdgeInsetsZero; } }
對(duì)cell的LayoutMargins屬性的設(shè)置
對(duì)cell的設(shè)置可以寫(xiě)在cellForRowAtIndexPath里,也可以寫(xiě)在willDisplayCell方法里
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"cell"; FSDiscoverSpecialCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (cell == nil) { cell = [[FSDiscoverSpecialCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } //2.調(diào)整(iOS8以上)tableView邊距(與上面第2步等效,二選一即可) if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) { cell.preservesSuperviewLayoutMargins = NO; } //3.調(diào)整(iOS8以上)view邊距 if ([cell respondsToSelector:@selector(setLayoutMargins:)]) { [cell setLayoutMargins:UIEdgeInsetsZero]; } return cell; }
三種方法優(yōu)缺點(diǎn)比較:
方法1是比較好用的,但是有些情況下系統(tǒng)自帶的cell就足夠用了,僅僅為了分隔線卻還必須再自定義cell,添加一個(gè)view,設(shè)置背景顏色和frame,又顯得麻煩;
方法2比較取巧,但是也需要自定義cell,在某些情況下不允許改變tableView的背景色,使用場(chǎng)景有限;
方法3不需要自定義cell,對(duì)系統(tǒng)(iOS7,iOS8以上)做個(gè)簡(jiǎn)單判斷即可.可惜網(wǎng)上很多文章寫(xiě)的不對(duì),很多人不會(huì)正確使用,有些會(huì)用的人也說(shuō)不清楚原理,只管復(fù)制粘貼.
比如網(wǎng)上流傳的一般是這樣,需要四步,雖然真的管用,但多了一步[cell setSeparatorInset:UIEdgeInsetsZero];而且原理也沒(méi)講,估計(jì)是某大神寫(xiě)的,根本不屑于過(guò)多解釋,讓我用起來(lái)很郁悶,網(wǎng)上流傳代碼:
首先在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]; } }
其實(shí)關(guān)于分隔線不能全屏的原理,蘋(píng)果官方在文件中已經(jīng)說(shuō)明了,可以去看一下
在iOS7之前系統(tǒng)默認(rèn)就是全屏的,iOS7時(shí)UITableView多了separatorInset屬性,可在UITableView的頭文件中查看,如下:
@property (nonatomic) UIEdgeInsets separatorInset NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; // allows customization of the frame of cell separators
iOS7時(shí)只要設(shè)置該屬性為UIEdgeInsetsZero就沒(méi)有問(wèn)題了.
iOS8之后僅僅完成以上設(shè)置就不行了,仔細(xì)查看后發(fā)現(xiàn)iOS8的UIView的頭文件里又多了個(gè)layoutMargins屬性,并有官方注釋
@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.
*/
大意是說(shuō):layoutMargins是view的bounds的邊距,用來(lái)調(diào)整內(nèi)容默認(rèn)邊距
如果preservesSuperviewLayoutMargins屬性是YES,那么設(shè)置父控件的layoutMargins邊距,就會(huì)影響所有子控件的相對(duì)于父控件bounds的layoutMargins邊距
如果你的view的子類(lèi)在布局或者繪圖中使用了layoutMargins屬性,需要重寫(xiě)-layoutMarginsDidChange 方法,以便當(dāng)邊距改變時(shí)能刷新你的view
正是因?yàn)閘ayoutMargins是UIView的新增屬性,tablet和cell作為UIView的子類(lèi)都有這個(gè)屬性,所以相比較iOS7系統(tǒng),iOS8之后就多了兩步,必須同時(shí)再對(duì)tableView和cell的layoutMargins屬性進(jìn)行處理,才能讓分隔線真正全屏.
同時(shí)官方注釋中對(duì)preservesSuperviewLayoutMargins(意即:維持父控件的布局邊距)屬性的說(shuō)明,也正好能說(shuō)明網(wǎng)上另一種方法不設(shè)置self.tableView.layoutMargins = UIEdgeInsetsZero;
而是設(shè)置cell.preservesSuperviewLayoutMargins = NO;
為什么也能起作用
弄清楚了這些原理,就可以更好的記憶和使用這些方法,不用每次都去舊代碼查找或者去百度了.
說(shuō)到了最后,不知道大家有沒(méi)有覺(jué)得影響分隔線全屏的元兇layoutMargins屬性 稍微有點(diǎn)眼熟呢?其實(shí)它在另一個(gè)地方也做了不少惡,就在storyboard中:
PS:附效果圖如下:
設(shè)置之前效果圖:
設(shè)置完第1步self.tableView.separatorInset = UIEdgeInsetsZero;
后效果圖:
設(shè)置完第2步self.tableView.layoutMargins = UIEdgeInsetsZero;
后效果圖:
設(shè)置完第3步cell.layoutMargins = UIEdgeInsetsZero;
后效果圖:
附:設(shè)置UITableView的單元格分割線離屏幕左右的距離為0
在開(kāi)發(fā)中,有時(shí)候?yàn)榱私缑娴拿烙^,需要表示圖的分割線左右間距為0,即呈現(xiàn)下面的效果
有時(shí)候就直接取消顯示表視圖的分割線,然后在單元格內(nèi)直接添加一條直線,這樣也能滿(mǎn)足要求,還有一種方法是改變表視圖內(nèi)部的分割線的偏移量來(lái)實(shí)現(xiàn),具體代碼如下:
if ([_tableView respondsToSelector:@selector(setSeparatorInset:)]) { [_tableView setSeparatorInset:UIEdgeInsetsMake(0,0,0,0)]; } if ([_tableView respondsToSelector:@selector(setLayoutMargins:)]) { [_tableView setLayoutMargins:UIEdgeInsetsMake(0,0,0,0)]; }
//代理方法 -(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]; } }
這樣,就實(shí)現(xiàn)了單元格分割線的滿(mǎn)格顯示了。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
IOS 下獲取 rootviewcontroller 的版本不同的問(wèn)題解決辦法
這篇文章主要介紹了IOS 下獲取 rootviewcontroller 的版本不同的問(wèn)題解決辦法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家遇到這種問(wèn)題可以解決,需要的朋友可以參考下2017-10-10深入詳解Objective-C中的@Synchronized關(guān)鍵字
這篇文章主要為大家介紹了深入詳解Objective-C中的@Synchronized關(guān)鍵字,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03IOS中用正則表達(dá)式判斷輸入的內(nèi)容為8-16位且同時(shí)包含數(shù)字和字母
這篇文章主要介紹了IOS中用正則表達(dá)式判斷輸入的內(nèi)容為8-16位且同時(shí)包含數(shù)字和字母,需要的朋友可以參考下2017-06-06iOS實(shí)現(xiàn)“搖一搖”與“掃一掃”功能示例代碼
本篇文章主要介紹了iOS實(shí)現(xiàn)“搖一搖”與“掃一掃”功能示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01iOS基礎(chǔ)知識(shí)之@property 和 Ivar 的區(qū)別
這篇文章主要介紹了iOS基礎(chǔ)知識(shí)之@property 和 Ivar 的區(qū)別介紹,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08iOS 控制器自定義動(dòng)畫(huà)跳轉(zhuǎn)方法(模態(tài)跳轉(zhuǎn))
下面小編就為大家分享一篇iOS 控制器自定義動(dòng)畫(huà)跳轉(zhuǎn)方法(模態(tài)跳轉(zhuǎn)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01iOS 11 使用兩種方法替換(Method Swizzling)去掉導(dǎo)航欄返回按鈕的文字
這篇文章主要介紹了iOS 11 使用方法替換(Method Swizzling)去掉導(dǎo)航欄返回按鈕的文字,需要的朋友可以參考下2018-05-05