iOS UITableView 滑动时顺序混乱或多个cell内容相同

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS UITableView 滑动时顺序混乱或多个cell内容相同相关的知识,希望对你有一定的参考价值。

在使用UITableView时,由于cell的重用机制,在获取后台数据并填充cell时,会发生cell重复出现,界面紊乱。但这仅仅在拥有多个section的情况下会出现,没有滚动的时候,单个section的row显示的都是正确的。

 

以下是示例代码:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//这个方法是UITableView 的 DataSource方法,作用是用来加载/重用cell的。
 
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
    
//  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
 
    if (cell == nil) {
        // ... your code
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier: SimpleTableIdentifier];
    }
    return cell;
}

 

这里面的变量其实每创建一次tableViewController都会出现

1. SimpleTableIdentifier:cell的标识, dequeueReusableCellWithIdentifier方法会用到。在alloc cell的时候会传入SimpleTableIdentifier并赋给cell的reuseIdentifier属性
。如果使用dequeueReusableCellWithIdentifier来获取cell,就要确保每个indexPath.row所指向的cell的SimpleTableIdentifier唯一。

2. dequeueReusableCellWithIdentifier::这个方法会返回reuseIdentifier与当前SimpleTableIdentifier相同的cell,这也就是造成顺序混乱的原因,如果没有找到,返回nil

3. cellForRowAtIndexPath::这个方法会返回与当前indexPath相同的cell,所以就算是所有cell的SimpleTableIdentifier都相同,也会得到正确顺序,如果没有找到,返回nil

 

总结

如果在你的程序中,出现排序混乱或cell内容相同的情况,请核对使用的是dequeueReusableCellWithIdentifier方法还是cellForRowAtIndexPath方法。

由于cellForRowAtIndexPath方法不会出现这种情况,所以如果使用的是dequeueReusableCellWithIdentifier方法,请确保每个cell的reuseIdentifier唯一。

但是cell重用的机制也不能忽略,UITableViewCell有一个队列用来专门存放那些生成过的,但是后来由于滚动tableView而隐藏起来的cell,

比如一个table有20个cell,但是屏幕只能显示5个,(当然iPhone5可能会显示6个),那么就会有其他的cell没有显示出来,但是在滑动tableview的时候便会显现。

而代码中:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];

 

就是从队列中根据标示符取出一个暂时不用的cell,只有cell为nil,也就是队列中没有旧的cell的时候,才会执行:

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier: SimpleTableIdentifier];

以此生成一个新的cell。

如果有旧的,就不用执行这个语句了,这样节省资源,算作一种重用。

 

在tableView初始化的时候队列中肯定没有cell的,所以每个cell生成的时候都会执行一遍这个代码:

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier: SimpleTableIdentifier];

 

当屏幕显示满了,向上滚动显示下一行时,就会把第一行隐藏,放到那个队列中,然后新增加的一行执行语句:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
这时候结果就不是nil了,然后,就跳过语句2了,这样就节约资源了。

以上是关于iOS UITableView 滑动时顺序混乱或多个cell内容相同的主要内容,如果未能解决你的问题,请参考以下文章

滑动删除 UITableView (iOS) 中的整个部分

iOS 7 UITableView 问题 - 当我们已经有一个单元格时尝试设置滑动以删除单元格

iOS 从 UITableView 滑动以删除 plist 中的数组

iOS UITableView的横向滑动

如何在 UITableView Cell 中实现类似于 iOS 邮件的从左向右滑动

iOS开发-UITableView滑动视差