2011-05-10 121 views
1

我正面临一些奇怪的问题。每当我滚动我的表格视图时,我的数据被替换为其他单元格。每一次,它都会被不同的单元格数据取代。我没有看到这个替代品有任何特定的模式。滚动时显示的单元格数据不正确UITableView

+4

您并未重复使用/正确创建单元格。发布您的cellForRowAtIndexPath方法,我们将能够指出错误 – Vladimir 2011-05-10 15:07:35

+3

需要查看'tableView:cellForRowAtIndexPath:'的代码。 – PeyloW 2011-05-10 15:10:10

回答

7

下面是如何正确地重用单元代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"CellIdentifier"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) {   
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    // Configure the cell... 
    cell.textLabel.text = [array objectAtIndex:indexPath.row]; 

    return cell; 
} 

如果您提供的代码,我们可以修改,而不是给你普通的例子。

+0

嗨,谢谢你的答复。但是如果我在单元格分配行之后完成了if(cell == nil)的括号,我的日期会相互重叠。 – user714236 2011-05-10 18:16:10

+0

@user如果你的日期相互重叠,那是因为你没有正确处理日期。这是处理可重用细胞的正确方法。如果你认真寻求帮助,你应该发布一些代码。我的猜测是,您要么每次添加新的子视图,要么手动绘制它们,您在绘制日期之前未清除表面。 – 2011-05-10 21:41:23

+0

这不仅是单元重用的问题。在iOS 6.0中,有一个很好的方法来解决这个问题:http://stavash.wordpress.com/2012/12/14/advanced-issues-asynchronous-uitableviewcell-content-loading-done-right/ – Stavash 2012-12-14 16:07:12

4

如果您创建了自定义单元格,则可能必须在UITableViewCell子类上实施prepareForReuse以清除单元格数据。

7
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease]; 
+0

Thanks Rams.I得到了解决方案。我没有给复用标识符,它对我来说非常完美。 – user714236 2011-05-17 14:37:54

+1

yes this reuseIdentifier:nil也帮助我.. – 2012-09-27 10:29:01

+0

非常感谢你的工作。我的细胞每次都在变化。 – 2013-12-22 13:49:46

0

旧的,但仍然... 我遇到了这个问题。如果其他人有一天看到这个问题。 我没有注意到,也不记得我为什么这么做,但是我写了测试if (cell == nil)里面的单元格的配置,而不是在写完之后写入它。我一定累了这一天...

1

我在iOS 7和故事板上有同样的问题,而我从来没有在老年人Xcode-SDK版本上使用相同的代码的这个问题,并尝试从stackoverflow很多建议,我无法修复它,并猜测是什么?!苹果的TableView Programming Guide有很好的解释指南。 甚至不需要使用cell==nil

所以要创建一个使用故事板的自定义tableview单元格,可以正确重用,可以采取两种不同的方法。我个人更喜欢第一个更直接的,但我把这两个解决方案放在这里。

第一种方法

  1. 创建一个使用主从应用模板的项目,并选择使用故事板选项。
  2. 在故事板画布上,选择主视图控制器。
  3. 在Identity检查器中,验证Class是否设置为自定义MasterViewController类。
  4. 选择主视图控制器内部的表格视图。
  5. 在属性检查器中,验证内容弹出式菜单是否设置为动态原型。
  6. 选择原型单元格。
  7. 在属性检查器中,在样式弹出菜单中选择自定义。
  8. 在标识符文本字段中输入重用标识符。 这是与发送到dequeueReusableCellWithIdentifier:消息中的表视图相同的重用标识符。
  9. 在Accessory弹出菜单中选择Disclosure Indicator。
  10. 将库中的对象拖动到单元格上。 对于此示例,拖动两个标签对象并将它们放在靠近单元格末端的位置(为附件视图留出空间)。
  11. 选择对象并设置其属性,大小和自动修改特征。

为此过程的编程部分设置的一个重要属性是每个对象的tag属性。在Attributes inspectorView部分中查找此属性,并为每个对象分配一个唯一的整数。

现在编写您通常会写入的代码以获取表视图的数据。 (在本例中,您需要的唯一数据是每个单元格的行号。)实现数据源方法tableView:cellForRowAtIndexPath:从原型创建一个新单元格,并使用数据填充它,其方式与此代码类似:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"]; 

    UILabel *label; 

    label = (UILabel *)[cell viewWithTag:1]; 
    label.text = [NSString stringWithFormat:@"%d", indexPath.row]; 

    label = (UILabel *)[cell viewWithTag:2]; 
    label.text = [NSString stringWithFormat:@"%d", NUMBER_OF_ROWS - indexPath.row]; 

    return cell; 
} 

有此代码的几个方面需要注意:

  • 分配给原型电池的串标识符是你传递给在dequeueReusableCellWithIdentifier:表视图相同的字符串。
  • 因为原型单元格是在故事板中定义的,所以dequeueReusableCellWithIdentifier:方法总是返回一个有效的单元格。您无需检查返回值nil并手动创建单元格。
  • 代码通过调用viewWithTag:传入其标签整数来获取单元中的标签。然后它可以设置标签的文本内容。

第二种方法

如果你不喜欢使用标签,您可以使用另一种方法设置单元格中的内容。为要设置的对象定义一个带有插座属性的自定义UITableViewCell子类。在故事板中,将新类与原型单元相关联,并将出口连接到单元中的相应对象。

要使用网点的自定义单元格内容

  1. 名为MyTableViewCell的Objective-C类添加到您的项目。
  2. 下面的代码添加到所述接口中MyTableViewCell.h

    @interface MyTableViewCell:的UITableViewCell

    @属性(非原子,弱)IBOutlet中的UILabel * firstLabel; @property(非原子,弱)IBOutlet UILabel * secondLabel; @end

  3. 下面的代码添加到实施MyTableViewCell.m

    @synthesize firstLabel,secondLabel;

  4. 下面的代码行添加到实现该数据源的源文件:

    #进口“MyTableViewCell。H”

  5. 使用Identity inspector原型细胞的类设置为MyTableViewCell

  6. 使用连接检查员在原型细胞中的两个出口连接到其相应的标签。 enter image description here

  7. 执行数据源方法tableView:cellForRowAtIndexPath:

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"]; 
    
    cell.firstLabel.text = [NSString stringWithFormat:@"%d", indexPath.row]; 
    cell.secondLabel.text = [NSString stringWithFormat:@"%d", NUMBER_OF_ROWS - indexPath.row]; 
    
    return cell; 
    } 
    

代码使用访问器方法获取对单元中标签的访问权限(此处使用点标记)。代码然后可以设置标签的文本内容。

相关问题