UITableView滚动问题

时间:2011-09-20 08:37:16

标签: iphone uitableview scroll cell

我有一个带有自定义单元格的TableView,其中一些有图像,有些则没有。一切正常,但是当我开始滚动时,细胞显示不正确(图像被放置在“错误的”单元格中并在中间切割)。现在有人怎么解决这个问题?

3 个答案:

答案 0 :(得分:4)

要理解的关键是你的桌子的细胞被重复使用。这样做是为了提高滚动性能,因为创建一个新单元 - 这是一个视图 - 非常昂贵。

在方法cellForRowAtIndexPath中,返回一个单元格。使用dequeue方法的现有单元格,或者您创建一个新单元格。在该单元格上,您可以设置您希望表示的任何属性。

我的猜测是你直接在单元格上设置图像等属性。然后滚动时,该单元格会被重复使用,您会再次看到相同的图像但是在错误的单元格上。

所以,你需要的是像NSArray这样的单独索引来维护你的模型对象。该模型对象包含图像的所有细节等。

我们举一个例子。我有一个包含10个对象的数组,前五个是图像“a.png”,第二个是“b.png”。

如果我收到cellForRowAtIndexPath的回调,我想按以下步骤操作:

  

cellForRowAtIndexPath:(0,0)从数组中提供索引0的对象,即a.png   cellForRowAtIndexPath:(0,1)从数组中提供索引1的对象,即a.png   cellForRowAtIndexPath:(0,2)从数组中提供索引2的对象,即a.png   cellForRowAtIndexPath:(0,3)从数组中提供索引3的对象,即a.png   cellForRowAtIndexPath:(0,4)从数组中提供索引4的对象,即a.png   cellForRowAtIndexPath:(0,5)从数组中提供索引5的对象,即b.png   cellForRowAtIndexPath:(0,6)从数组中提供索引6的对象,即b.png   cellForRowAtIndexPath:(0,7)从数组提供索引7的对象,即b.png   cellForRowAtIndexPath:(0,8)从数组中提供索引8的对象,即b.png   cellForRowAtIndexPath:(0,9)从数组中提供索引9的对象,即b.png

现在,让我们考虑在UITableView中,在封面下,五个单元格正在被重用。

对于上面的每个电话,都会发生以下情况:

  

cellForRowAtIndexPath:(0,1)从数组中提供索引1的对象,即a.png    - 您尝试将现有单元格出列但它返回“nil”,因此您创建了一个新单元格。您可以设置模型对象的详细信息。

     

cellForRowAtIndexPath:(0,2)从数组中提供索引2的对象,即a.png    - 您尝试将现有单元格出列但它返回“nil”,因此您创建了一个新单元格。您可以设置模型对象的详细信息。

     

cellForRowAtIndexPath:(0,3)从数组中提供索引3的对象,即a.png    - 您尝试将现有单元格出列但它返回“nil”,因此您创建了一个新单元格。您可以设置模型对象的详细信息。

     

cellForRowAtIndexPath:(0,4)从数组中提供索引4的对象,即a.png    - 您尝试将现有单元格出列但它返回“nil”,因此您创建了一个新单元格。您可以设置模型对象的详细信息。

     

cellForRowAtIndexPath:(0,5)从数组中提供索引5的对象,即b.png    - 你试图将现有的单元格出列并且它有效!您可以通过设置模型对象的详细信息再次使用该单元格

     

cellForRowAtIndexPath:(0,6)从数组中提供索引6的对象,即b.png    - 你试图将现有的单元格出列并且它有效!您可以通过设置模型对象的详细信息再次使用该单元格

     

cellForRowAtIndexPath:(0,7)从数组中提供索引7的对象,即b.png    - 你试图将现有的单元格出列并且它有效!您可以通过设置模型对象的详细信息再次使用该单元格

     

cellForRowAtIndexPath:(0,8)从数组中提供索引8的对象,即b.png    - 你试图将现有的单元格出列并且它有效!您可以通过设置模型对象的详细信息再次使用该单元格

     

cellForRowAtIndexPath:(0,9)从数组中提供索引9的对象,即b.png    - 你试图将现有的单元格出列并且它有效!您可以通过设置模型对象的详细信息再次使用该单元格

很抱歉这么冗长!我希望这有帮助。也许值得通过一个好的表视图教程。肯定会有很多人。

答案 1 :(得分:2)

尝试更改单元格的标识符值。

NSString* identifierStr = [NSString stringWithFormat:@"ident_%d",indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifierStr];

答案 2 :(得分:0)

您可能在创建单元格实例时添加图像,而不是在表格视图要求单元格视图时添加图像。例如:

这是正确的方法。每次表格视图要求一个单元格时,我们都会设置图像。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ident"];
    UIImageView *imageView;
    if (cell == nil) {
        cell = [UITableViewCell alloc] init ....];
        imageView = [[UIIMageView alloc] init];
        imageView.tag = 123;
        [cell addSubview:imageView];
        [imageView release];
    } else {
        imageView = [cell viewWithTag:123];
    }

    imageView.image = ...; // load image here
}

这是错误的方式。我们在创建单元格时设置图像。这将导致细胞在重复使用时出现错误的图像。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ident"];
    if (cell == nil) {
        cell = [UITableViewCell alloc] init ....];
        UIImageView *imageView = [[UIIMageView alloc] init];
        imageView.image = ...; 
        [cell addSubview:imageView];
        [imageView release];
    }

}