UITableViewCell可重用性导致问题[与图像]! [英] UITableViewCell Reusability causing Problems [with images] !

查看:117
本文介绍了UITableViewCell可重用性导致问题[与图像]!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一张图片值得一千字,我猜下面张贴的图片清楚地表达了我现在面临的问题。



这里是一个小结:



我创建一个tableView,每个tableViewCell有一个 textField 作为子视图。我向上和向下滚动,我的视图搞乱了。我猜这是因为 Cell Reusability

注意 这个问题是不是因为 uitextView在屏幕的底部。如果我没有他们,我只有前三个部分,textFields被移动,它弄乱了一个textFields的几个单元格。还要注意图像4中的textField移位与其他图像相比。代码粘贴在此处 http://www.pastie.org/2203340 p>

  ** PS:**我在问题末尾添加了问题的解决方案。 

这是我的常规视图



>



这是当我向下滚动时(见下面)





几次滚动向上和向下...(如下)
>



再进行几次卷动...(如下)
/ p>

解决方案



我真的非常感谢@caleb和其他人正确的方向,并帮助我修复这个bug。对于那些也面临同样问题的人,我认为我应该提供一个简短而甜蜜的答案。



使用具有不同CellIdentifier的UITableViewCells。这将确保相同的单元格不被调用。

解决方案

你猜测它与单元重用是正确的。我注意到的第一件事是,你使用相同的单元格标识符为所有的单元格。这意味着所有单元格被认为是相同的,你应该假设每个细胞的一切将必须每次配置。对不同类型的单元格使用不同的标识符会更容易,但我会让你嚼一些这么多...



无论如何,根你的问题是这个代码:

  if(section == 3){
cell = nil;
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;

if(indexPath.row == 0){
cell.backgroundColor = [UIColor clearColor];
cell.contentMode = UIViewContentModeScaleToFill;
[cell.contentView addSubview:self.footerView];
}
}

对于此特定单元格,颜色清除,添加footerView等。但是你不设置任何其他单元格的背景颜色,所以一旦这个特定的单元格恰好在不同的位置重复使用,你会得到清楚背景和其他修改。



现在,您可能会更容易看到为什么您可能想要为不同类型的单元格使用不同的单元格标识符。如果你使用不同的标识符作为你的清除单元格,而不是你的白色单元格,你不必担心清除单元格被回收作为白色单元格,反之亦然。您应该为每个单元格类型使用不同的标识符,其中单元格类型由您不想在每次重新使用单元格时配置的所有单元格属性定义。



您在 -reuseTableViewCellWithIdentifier:withIndexPath:方法中做了很多工作,最终使单元格不太可重用。相反,您应该确定要显示的单元格的每种不同的类型或样式,而不受其中显示的特定信息的影响。例如,前三个部分中的所有单元格都大致相同:它们都类似于 UITableViewCellStyleValue1 标准单元格样式,但细节标签为左侧空白,并在右侧添加文本字段。对所有这些单元格使用相同的重用标识符,然后。 -reuseTableViewCellWithIdentifier:withIndexPath:实际上不应该关心索引路径 - 它应该只创建和返回一个所需样式的单元格,由所提供的重用标识符确定。将这些单元格中的字段的文本设置为 -tableView:cellForRowAtIndexPath:方法。



我注意到,在创建每个单元格时,您正在存储索引路径和指向文本字段的指针。如果你重用单元格,这些都不会有帮助。



如果你永远不会添加更多的单元格,显示,它可能更简单,你可以简单地跳过整个重用的东西。重复使用单元格提供了明显的性能改进,当滚动通过一个表有数十或数百个单元格,但如果你永远不会有超过十或十五个单元格,其中一半在任何给定的时间在屏幕上,重用的优势细胞不是那么大。然而,我鼓励你花时间来理解这个想法;迟早要创建一个包含许多行的表。


A picture is worth a thousand words, and I am guessing that the pictures posted below clearly convey the problem I am facing now.

Here's a little summary:

I create a tableView, and each tableViewCell has a textField as a subview. I scroll up and down, and my view gets messed up. I am guessing it is because of Cell Reusability. But I need help with this.

Note: This problem is not because of the buttons or the uitextView at the bottom of the screen. If I do not have them, and I have only the first three sections, the textFields get shifted and it messes up a the textFields of several cells. Also notice the textField shift in image 4 compared to other images. The code is pasted here http://www.pastie.org/2203340

**P.S.:**   I have added the solution to the problem at the end of the question. 

This is my normal view

This is when I scroll down (look below)

After several scrolls Up and Down... (look below)

After several more scrolls... (look below)

SOLUTION :

I really thank @caleb and others for pointing me in the right direction and helping me fixing this bug. For those people, whom are also facing the same problem, I thought I should provide a short and sweet answer.

Use UITableViewCells with different CellIdentifiers. That would make sure that the same cell does not get called.

解决方案

Your guess that it has to do with cell reuse is correct. The first thing I noticed is that you're using the same cell identifier for all your cells. That means that all cells are considered the same, and you should assume that everything about a cell will have to be configured every time. It'd be easier to use different identifiers for different types of cells, but I'll let you chew on that much for a bit...

Anyway, the root of your problem is this code:

if (section ==3){
    cell =nil;
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (indexPath.row ==0){
        cell.backgroundColor = [UIColor clearColor];
        cell.contentMode = UIViewContentModeScaleToFill;
        [cell.contentView addSubview:self.footerView];
    }
}

For this particular cell, you're setting the background color to clear, adding the footerView, etc. But you don't set the background color for any of the other cells, so as soon as this particular cell happens to be reused in a different position, you're going to get the clear background and other modifications in that position.

Now it'll probably be easier to see why you might want to use different cell identifiers for different types of cells. If you use a different identifier for your clear cells than you do for your white ones, you don't have to worry about clear cells being recycled as white cells and vice versa. You should use a different identifier for each "cell type", where "cell type" is defined by all the cell attributes that you don't want to have to configure each time you reuse a cell.

You're doing a lot of work in your -reuseTableViewCellWithIdentifier:withIndexPath: method that ends up making the cells not very reusable. Instead, you should identify each different "type" or "style" of cell that you want to display independant of the particular information that's displayed in them. For example, all the cells in your first three sections appear to be about the same: they're all similar to the UITableViewCellStyleValue1 standard cell style, except that the detail label is left empty and a text field is added to the right side. Use the same reuse identifier for all these cells, then. -reuseTableViewCellWithIdentifier:withIndexPath: really shouldn't care about the index path -- it should just create and return a cell in the required style as determined by the supplied reuse identifier. Leave the work of setting the text of the fields in those cells to the -tableView:cellForRowAtIndexPath: method.

I notice that you're storing the index path and a pointer to the text field when you create each cell. Neither of these is going to help at all if you're reusing cells.

If you're never going to add more cells to the table than the ones you've shown, it may be simpler for you to simply skip the whole reuse thing. Reusing cells gives a marked performance improvement when scrolling through a table with dozens or hundreds of cells, but if you'll never have more than ten or fifteen cells, and half of those are on the screen at any given time, the advantage of reusing cells isn't that great. Nevertheless, I'd encourage you to spend the time to get your head around the idea; sooner or later you're going to want to create a table with many rows.

这篇关于UITableViewCell可重用性导致问题[与图像]!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆