我对tableView的一些理解

一、tableViewStyle的选择

tableview有两种style供我们选择,UITableViewStylePlain(默认)和UITableViewStyleGrouped。

1.grouped的sectionHeader不会悬浮。plain反之。

2.plain会出现多余的分割线,充满整个tableview,grouped不会。

具体选择那一种style,根据需求具体分析。个人比较喜欢UITableViewStylePlain,因为这样就不用再去专门做一个悬浮的sectionHeader,不会悬浮的header作为一个cell显示。

二、tableViewHeader

一般的页面都会有一个比较固定的头部,它们通常比较复杂,不用经常更新,UI数据也不用后台返回。这时候就需要我们的tableViewHeader。

tableViewHeader会随着tableView一起滑动。

tableViewHeader默认为nil,需要重新去赋值一个view;

需要注意的点:
通常我们习惯用masonry或者其他的一些自动化布局,但是tableViewHeader的高度,在layoutsubViews方法执行之前,默认为0。
所以我们需要在layoutsubViews之后,进行masonry布局,不然会报UI警告。(个人洁癖,其实无伤大雅)

另外一点,头部的图片,如果size超过了imageView的大小,记得设置maskToBounds,不然在ipad上面,会出现图片的溢出,遮挡住其他控件。

三、sectionHeader和cell

这两个一起说,其实在我看来,他们本质上是一致的:可以放到缓存池中被重用的view。
而tableView呢,是他们的一种布局方式,是collectionView的一种特殊布局,这个后面再说。

我只聊一下对cell的看法,sectionHeader可以比照着理解。

1、注册cell

比如注册一个LyTableViewCell,重用ID为LyTableViewCellId:

[tableView registerClass:[LyTableViewCell class] forCellReuseIdentifier:@"LyTableViewCellId"]

其实这是一个把LyTableViewCell注册到缓存池的操作,同样的,滑动tableView时释放cell,也会执行这个操作。
所以,你可以找到一个替代注册cell的方式:

LyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LyTableViewCellId"];
if (!cell) {
  cell = [[LyTableViewCell alloc] init];
}

先从缓存池中取id为LyTableViewCellId的cell,如果为空,则初始化该cell。

2、cell的重用

每一个消失在屏幕上面的cell都会被放到缓存池中,等待被重用。
而重用这一操作,对我们原生开发来说,就是对一个cell重新赋值的过程。

比如对于一个cell,tabLabel可以是“半价”,可以是“精选”,也可以是隐藏状态,在我们重用时,就要充分考虑到所有cell的可能情况,对该cell进去相应的操作。
初学者出现的,cell的各种UI小问题,大部分都是这个原因。

重用时执行的方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

大部分cell是需要重用的,这也是tableView在数据庞大时仍能保持高性能的原因。但是有些特殊的cell,比如"状态选择类"的,每次重新赋值,会导致状态的丢失,这时候就需要做一些特殊的操作,保证不被复用。

我的方式也很简单,在cellModel中,加一个singleIdentifier的属性,如果检测到,则不进行赋值,直接返回。(我习惯一个cell对应一个cellModel,如果大家没有这种习惯,其他类似方式也可以解决)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  {...}
  NSString *identifier = cellModel.singleIdentifier;
  BOOL forceRefresh = cellModel.forceRefresh;
  if (identifier && identifier.length > 0 && !forceRefresh)
  {
    return [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
  }
  {...}
}

这种写法会导致任何情况下都不会赋值,所以需要多加一个forceRefresh属性控制,是否强制刷新。

3、cell的点击

实现两个代理方法就可以了:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0);

设置cell的selected为true之后,下次点击就会执行didDeselectRowAtIndexPath方法。

点击操作就在这里面执行。

如果要设置高亮状态的UI,则在cell的设置方法里面进行操作:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated;
4、cell的高度

cell的高度,API给了我们两个属性进行设置

rowHeightestimatedRowHeight,这两个都是默认UITableViewAutomaticDimension,自适应高度,我们可以根据需求去配置相应的属性。

rowHeight:顾名思义,用在已经确定了高度的cell,设置之后就会固定cell的高度。

estimatedRowHeight:估算高度,用得好的话可以提高tableView的性能。
这个值不可以乱设,tableView在刷新页面时,会先将cell默认为estimatedRowHeight的高度去布局,如果和实际高度相差过大,tableView会出现闪动、改变偏移量的现象。
所以,估算高度,和实际高度不能有太大的误差。

API还提供了两个方法,根据cell去设置高度。方法优先级高于统一设置的属性。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath

四、代理方法

UITableViewDataSource:数据
传tableView的一些基础数据,如个数,cell数据;
负责cell的移动,删减,增加。

UITableViewDelegate:UI显示
遵循UIScrollViewDelegate;
负责如cell的显示,高度,预估高度,高亮状态,点击状态等等的回调;

为什么单拎出来说呢,因为这样我们可以明显的看到,苹果有意把tableView分成两个部分,数据和UI。
对应我们原生的工作,就是UI搭建和建模。
所以我们也可以把这两块分开来做,不要纠缠在一起。

数据由后台传递,是动态变化的。UI是我们自己搭建,相对格式化的,然后在tableView中对应起来。

这些大概就是小弟的一些浅见。
总有人觉得,tableView这么简单的东西,为什么还要专门去研究呢。但在我看来,见微知著,如果能把这个东西搞透彻,就有了去研究更深一级的collectionView的门槛,collectionView也琢磨透了,UI的展示类布局基本就算是可以出师了。
当然了,学无止境。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容