iOS TableView中的一些問題

iOS11.0中的 tableView

在iOS11中如果不實現(xiàn)-tableView: viewForHeaderInSection:和-tableView: viewForFooterInSection:
則-tableView: heightForHeaderInSection:和- tableView: heightForFooterInSection:不會被調(diào)用
導(dǎo)致它們都變成了默認(rèn)高度别洪,這是因為tableView在iOS11默認(rèn)使用Self-Sizing,在創(chuàng)建 tableView 的時候,添加如下代碼

 if (@available(iOS 11.0, *)) {
        
        UITableView.appearance.estimatedRowHeight = 0;
        UITableView.appearance.estimatedSectionFooterHeight = 0;
        UITableView.appearance.estimatedSectionHeaderHeight = 0;
        UITableView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        
    } else {
        self.automaticallyAdjustsScrollViewInsets = NO;
    }

UITableView 點一下才刷新列表

異步讀取數(shù)據(jù),在異步中刷新數(shù)據(jù)(reloadData)

可能在比較慢的Mac上的模擬器上跑的時候沒有什么問題,但是在真機調(diào)試的時候就會出現(xiàn)bug.比如,打開app的時候不自動顯示數(shù)據(jù)列表,點擊一下,才會出現(xiàn)數(shù)據(jù)列表.

很有可能就是出現(xiàn)在子線程中reloadData.我們要把該過程放入主線程中:

dispatch_async(dispatch_get_main_queue(), ^{        
        self.dataSourceArray= a new Array;
        [self.tableView reloadData];
});

原理解釋:
在tableView的dataSource被改變 和 tableView的reloadData被調(diào)用之間有個時間差钟鸵,而正是在這個期間映砖,tableView的delegate方法被調(diào)用,如果新的dataSource的count小于原來的dataSource count郊楣,crash就很有可能發(fā)生了。

Always change the dataSource 'and(注意這個and)' reloadData in the mainThread. What's more, reloadData should be called 'immediately' after the dataSource change.
If dataSource is changed but tableView's reloadData method is not called immediately, the tableView may crash if it's in scrolling.
Crash Reason: There is still a time gap between the dataSource change and reloadData. If the table is scrolling during the time gap, the app may Crash!!!!

UITableView的復(fù)用

都知道UITableView 會根據(jù)復(fù)用的ID來對UITableViewCell進行復(fù)用,防止 UITableView 中不斷創(chuàng)建 cell,導(dǎo)致內(nèi)存暴漲.

  • 大致原理:
    比如:在當(dāng)前界面的數(shù)組dataArr.count = 20,但是當(dāng)前界面初始最多只能顯示7個(底部顯示一點點的也算),這7個 cell 就是剛運行的時候創(chuàng)建的,這些創(chuàng)建的 cell 會放到緩存池中.再往下滑動,或者下滑了之后再往上滑,會根據(jù)你事先設(shè)置的reuseIdentifier到緩存池中去取 cell,然后對 cell 上的控件重新賦值,顯示出來

  • 代碼實踐

// 定義一個 tableView 控件
@property(nonatomic,strong)UITableView *tableView;
// 對tableView 進行懶加載
-(UITableView* )tableView{
    
    if (!_tableView) {
        
        // UITableViewStyleGrouped
        _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, CIO_SCREEN_WIDTH, CIO_SCREEN_HEIGHT)];
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.backgroundColor  = [UIColor whiteColor];
    } 
    return _tableView;
}

tableView 創(chuàng)建完畢,就是遵循實現(xiàn) datasource ,delegate 的代理方法.

  1. 如果創(chuàng)建的時候沒有對該tableView的重用標(biāo)志符設(shè)置,可以這樣處理
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"cellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"section -- %ld, row -- %ld", indexPath.section, indexPath.row];
    cell.textLabel.textColor = [UIColor blueColor];
    cell.backgroundColor = [UIColor lightGrayColor];
    return cell;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
     //  如果緩存池有足夠的 cell 了,可以通過重用標(biāo)志符直接復(fù)用,不用在if (!cell1)重新創(chuàng)建了
    UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:@"cellOne"];
    if (!cell1) {
        // 這里都是初始化后創(chuàng)建的那些,就是需要創(chuàng)建的那7個
        cell1 = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellOne"];
        cell1.selectionStyle = UITableViewCellSelectionStyleNone;
    }  
    return cell1;
}
  1. 如果不想用上述辦法,還可以在創(chuàng)建tableView的時候加上:
//  為 tableView 注冊一個重用標(biāo)志符為 cellOne 的 UITableViewCell
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cellOne"];

然后在代理方法中,直接調(diào)用重用即可

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
     //  如果緩存池有足夠的 cell 了,可以通過重用標(biāo)志符直接復(fù)用,不用在if (!cell1)重新創(chuàng)建了
    UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:@"cellOne"];
 cell1.selectionStyle = UITableViewCellSelectionStyleNone;
   cell1.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell1;
}
  1. 可以自己編寫代碼,然后斷點進行調(diào)試,會對2種方法有更深入的了解

設(shè)置TableViewCell 分割線全屏寬度

  • 在自定義的 TableViewCell 中加入一下代碼
  if ([self respondsToSelector:@selector(setSeparatorInset:)]) {
        [self setSeparatorInset:UIEdgeInsetsZero];
    }
    
    if ([self respondsToSelector:@selector(setLayoutMargins:)]) {
        [self setLayoutMargins:UIEdgeInsetsZero];
    }
    
    if([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]){
        [self setPreservesSuperviewLayoutMargins:NO];
    } 
  • 使用系統(tǒng)的 UITableViewCell 時,也可以在創(chuàng)建cell 的 datasource 方法中加入以下代碼,同樣的效果
- (UITableViewCell *)tableView:(UITableView *)tableView
     cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
    [tableView dequeueReusableCellWithIdentifier:@"myCell"];

if (cell == nil) {
  cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                reuseIdentifier:@"myCell"];
}

if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
    [cell setSeparatorInset:UIEdgeInsetsZero];
}

if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
    [cell setLayoutMargins:UIEdgeInsetsZero];
}

if([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]){
    [cell setPreservesSuperviewLayoutMargins:NO];
}

} 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末猜谚,一起剝皮案震驚了整個濱河市麻献,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌症歇,老刑警劉巖郎笆,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異忘晤,居然都是意外死亡宛蚓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門设塔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凄吏,“玉大人,你說我怎么就攤上這事闰蛔『鄹郑” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵序六,是天一觀的道長任连。 經(jīng)常有香客問我,道長例诀,這世上最難降的妖魔是什么课梳? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任距辆,我火速辦了婚禮,結(jié)果婚禮上暮刃,老公的妹妹穿的比我還像新娘跨算。我一直安慰自己,他們只是感情好椭懊,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布诸蚕。 她就那樣靜靜地躺著,像睡著了一般氧猬。 火紅的嫁衣襯著肌膚如雪背犯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天盅抚,我揣著相機與錄音漠魏,去河邊找鬼。 笑死妄均,一個胖子當(dāng)著我的面吹牛柱锹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丰包,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼禁熏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了邑彪?” 一聲冷哼從身側(cè)響起瞧毙,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寄症,沒想到半個月后宙彪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡有巧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年您访,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剪决。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡灵汪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柑潦,到底是詐尸還是另有隱情享言,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布渗鬼,位于F島的核電站览露,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏譬胎。R本人自食惡果不足惜差牛,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一命锄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧偏化,春花似錦脐恩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至韵卤,卻和暖如春骗污,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沈条。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工需忿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜡歹。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓屋厘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親季稳。 傳聞我的和親對象是個殘疾皇子擅这,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

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