UITableView設(shè)置全屏分隔線的幾種方法比較


一般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)于分隔線不能全屏的原理,蘋果官方在文件中已經(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的子類在布局或者繪圖中使用了layoutMargins屬性,需要重寫(xiě)-layoutMarginsDidChange 方法,
以便當(dāng)邊距改變時(shí)能刷新你的view

正是因?yàn)閘ayoutMargins是UIView的新增屬性,tablet和cell作為UIView的子類都有這個(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中:

QQ20150413-000@2x.png


PS:附效果圖如下:


設(shè)置之前效果圖:

QQ20150411-111@2x.png

設(shè)置完第1步self.tableView.separatorInset = UIEdgeInsetsZero;后效果圖:
QQ20150411-222@2x.png

設(shè)置完第2步self.tableView.layoutMargins = UIEdgeInsetsZero;后效果圖:
QQ20150411-333@2x.png

設(shè)置完第3步cell.layoutMargins = UIEdgeInsetsZero;后效果圖:
QQ20150411-444@2x.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涩嚣,更是在濱河造成了極大的恐慌怕品,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驳概,死亡現(xiàn)場(chǎng)離奇詭異剔蹋,居然都是意外死亡趟畏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門滩租,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人利朵,你說(shuō)我怎么就攤上這事律想。” “怎么了绍弟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵技即,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我樟遣,道長(zhǎng)而叼,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任豹悬,我火速辦了婚禮葵陵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞻佛。我一直安慰自己脱篙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布伤柄。 她就那樣靜靜地躺著绊困,像睡著了一般。 火紅的嫁衣襯著肌膚如雪适刀。 梳的紋絲不亂的頭發(fā)上秤朗,一...
    開(kāi)封第一講書(shū)人閱讀 52,713評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音笔喉,去河邊找鬼取视。 笑死,一個(gè)胖子當(dāng)著我的面吹牛常挚,可吹牛的內(nèi)容都是我干的贫途。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼待侵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼丢早!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤怨酝,失蹤者是張志新(化名)和其女友劉穎傀缩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體农猬,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赡艰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了斤葱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慷垮。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖揍堕,靈堂內(nèi)的尸體忽然破棺而出料身,到底是詐尸還是另有隱情,我是刑警寧澤衩茸,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布芹血,位于F島的核電站,受9級(jí)特大地震影響楞慈,放射性物質(zhì)發(fā)生泄漏幔烛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一囊蓝、第九天 我趴在偏房一處隱蔽的房頂上張望饿悬。 院中可真熱鬧,春花似錦聚霜、人聲如沸乡恕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)傲宜。三九已至,卻和暖如春夫啊,著一層夾襖步出監(jiān)牢的瞬間函卒,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工撇眯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留报嵌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓熊榛,卻偏偏與公主長(zhǎng)得像锚国,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子玄坦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容