2011-09-20 89 views
2

我有一个自定义单元格,其中一些有图像和其他人没有的表格视图。一切工作正常,但当我开始滚动时,单元格显示不正确(图像放置在“错误”单元格中并切割)。现在有人如何解决这个问题?UITableView滚动问题

+1

显示单元构造的代码会帮助你。 – Jhaliya

+0

代码真的很大,但主要目的是在必要时添加图像并相应地编辑单元格高度。 – superM

+0

你在桌子上使用多个部分? – Jhaliya

回答

4

要理解的关键是您的表单元格被重用。这样做是为了增加滚动的性能,因为创建一个新的单元 - 这是一个视图 - 是非常昂贵的。

在方法cellForRowAtIndexPath中,返回一个单元格。使用出队方法的现有单元,或者您创建一个新单元。在那个单元格上,你可以设置你想表示的所有属性。

我的猜测是你直接在单元格上设置这些属性,如图像等。然后,当您滚动时,该单元格被重用,并且您再次看到相同的图像,但位于错误的单元格中。

所以,你需要的是像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)从数组a中提供对象索引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,这是一个。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 - 您试图使现有单元出队作品!您可以通过设置模型对象的详细信息再次使用该单元格

对不起,如此冗长!我希望这有帮助。也许这是值得通过一个很好的表格视图教程。肯定会有很多。

+0

非常感谢,它真的很有帮助。 – superM

+0

极好的例子。 – Jhaliya

+0

oops我做了一些数组索引错误。现在解决在上面的编辑。抱歉! –

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]; 
    } 

} 
+0

所以,如果我说得对,下一个单元是在前一个单元的“基础”上构建的? – superM

+0

类别。表视图将只创建尽可能多的单元格视图,因为它需要放入一个屏幕。然后,当您向下滚动时,消失的顶部单元格将被重新使用并通过'dequeueReusableCellWithIdentifier'添加到底部。因此,每次调用cellForRowAtIndexPath时,都需要确保配置单元格,而不仅仅是在创建单元格视图时。 –

+0

非常感谢您的帮助 – superM

2

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

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