iOS - UITableView中Cell重用机制致使Cell内容出错的解决办法

  "UITableView" iOS开发中重量级的控件之一;在平常开发中咱们大多数会选择自定Cell来知足本身开发中的需求, 可是有些时候Cell也是能够不自定义的(好比某一个简单的页面,只须要展现一些简单的信息);可是当页面大于屏幕显示的范围的时候, 滑动UITableView的时候,Cell上的内容会出现混乱或者错误的现象,通过反复的查找问题应该是出如今UITableViewCell的重用机制上;那么下面咱们就来讲一下解决这种问题的几种办法,以及最好的解决办法:ide

(一)使用系统的Cell,简单的Cell重用机制咱们会这样去写:测试

 1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 2     static NSString *cellIdentifier = @"cellID";
 3     
 4     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 5     
 6     if (!cell) {
 7         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
 8     }
 9     
10     // 说明: 要测试Cell内容是否错乱, 要将每行Cell显示的内容不一样, 才能看出来
11     cell.textLabel.text = @"Cell显示内容";
12     cell.detailTextLabel.text = @"Cell辅助显示内容";
13     
14     return cell;
15 }

  这样写虽然达到了Cell的重用, 可是会出现咱们要讨论的话题(滑动UITableView出现Cell内容混乱的状况),那么下面咱们就来讲一下避免Cell内容出现混乱的写法;spa

 

(二)使用系统的Cell,避免Cell内容出现混乱的写法:code

  (1)方法一:orm

    ①将得到Cell的方法:- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; 换为:- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;blog

    ②解决了Cell内容混乱的现象,可是没有可以达到Cell的重用机制的原理;由于cellForRowAtIndexPath(只从要更新的cell的那一行取出cell),不使用重用机制,于是问题就能够获得解决,可是会浪费一些空间(真机测试比其余方法略显卡顿);队列

    ③示例代码:开发

 1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 2     static NSString *cellIdentifier = @"cellID";
 3     
 4     // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 5     // 将上面的方法换成(根据indexPath准确地取出一行, 而不是从cell重用队列中取出, 方法以下:)
 6     UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
 7     
 8     if (!cell) {
 9         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
10     }
11     
12     // 说明: 要测试Cell内容是否错乱, 要将每行Cell显示的内容不一样, 才能看出来
13     cell.textLabel.text = @"Cell显示内容";
14     cell.detailTextLabel.text = @"Cell辅助显示内容";
15     
16     return cell;
17 }

  (2)方法二:rem

    ①经过为每一个cell指定不一样的重用标识符(reuseIdentifier)来解决;string

    ②重用机制是根据相同的标识符来重用Cell的,标识符不一样的Cell不能彼此重用;咱们将每一个Cell的标识符都设置为不一样,就能够避免不一样Cell重用的问题了;

    ③示例代码:

 1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 2     // static NSString *cellIdentifier = @"cellID";
 3     // 将上面的方法换成(以indexPath来惟一肯定Cell, 方法以下:)
 4     NSString *cellIdentifier = [NSString stringWithFormat:@"Cell%zd%zd", [indexPath section], [indexPath row]];
 5     
 6     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 7     
 8     if (!cell) {
 9         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
10     }
11     
12     // 说明: 要测试Cell内容是否错乱, 要将每行Cell显示的内容不一样, 才能看出来
13     cell.textLabel.text = @"Cell显示内容";
14     cell.detailTextLabel.text = @"Cell辅助显示内容";
15     
16     return cell;
17 }

  (3)方法三:

    ①经过删除重用的Cell的全部子视图,从而获得一个没有特殊格式的Cell,供其余Cell重用;

    ②示例代码:

 1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 2     static NSString *cellIdentifier = @"cellID";
 3     
 4     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 5     
 6     if (!cell) {
 7         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
 8     } else {
 9         // 删除Cell的全部子视图
10         while ([cell.contentView.subviews lastObject] != nil) {
11             [(UIView*)[cell.contentView.subviews lastObject] removeFromSuperview];
12         }
13     }
14     
15     // 说明: 要测试Cell内容是否错乱, 要将每行Cell显示的内容不一样, 才能看出来
16     cell.textLabel.text = @"Cell显示内容";
17     cell.detailTextLabel.text = @"Cell辅助显示内容";
18     
19     return cell;
20 }

  (以上即是对相关知识的相关介绍和理解,还但愿你们相互补充共同进步)

相关文章
相关标签/搜索