滚动时UITableCell内容损坏



我有一个UITableView,其中包含一个包含UIWebView的单元格,并且我的表格有2个问题。首先,Web 视图覆盖它所在的单元格,因此它使单元格看起来有点奇怪。

第二个更严重的问题和该线程的主要问题是滚动表时发生的损坏。随机地,Web 视图将在错误的单元格中呈现,我滚动得越快,像这样损坏的单元格就越多。如果我缓慢滚动,一切都会像它应该的那样呈现。

最初绘制表格时,会正确呈现该表。只有当用户滚动表格时,它才会开始变坏。当它搞砸时,UIWebView出现在一些不应该出现的单元格上。除非您滚动缓慢并且滚动速度越快,否则会发生这种情况。这不仅仅是一个图形故障,因为这些单元格中有一个不应该有的活动实时 Web 视图。我还注意到,我的单元格配件图标在第一个单元格上也从无更改为显示三角形。我尝试发布一些图片,但我太新了,不允许(垃圾邮件发送者破坏了每个人的乐趣)

这是我的cellForRowAtIndexPath代码。请温柔一点,我只是在学习这一切是如何工作的。:)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierMediaType];
    switch ([indexPath section]) {
        case 0: {
            if (!cell) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierLongDescription];
            }
            [cell.contentView addSubview:self.longDescriptionWebView];
            break;
        }
        case 1: {
            if (!cell) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierMediaType];
            }
            NSDictionary *cellDict = [self.subMediaTypes objectAtIndex:[indexPath row]];
            cell.textLabel.text = [cellDict objectForKey:@"SHORT_DESCRIPTION"];
            break;
        }    
        default:
            if (!cell) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierMediaType];
            }
            break;
    }
    return cell;
}

首先,我尝试在cellForRowAtIndexPath中定义重用单元格,但这会产生相同的结果,因此我将单元格移出并将它们设置为实例变量。这也有效,但我仍然有损坏问题,所以我猜测我在哪里设置重用单元真的无关紧要。这是我设置重用单元格的代码块。

if (!self.mediaTypeCell) self.mediaTypeCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierMediaType];
if (!self.longDescriptionCell) self.longDescriptionCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierLongDescription];
if (!self.longDescriptionWebView) self.longDescriptionWebView = [[UIWebView alloc] initWithFrame:self.longDescriptionCell.bounds];
self.mediaTypeCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
self.longDescriptionCell.accessoryType = UITableViewCellAccessoryNone;
[self.longDescriptionCell.contentView addSubview:self.longDescriptionWebView];
self.longDescriptionCell.contentView.autoresizesSubviews = YES;
self.longDescriptionWebView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.longDescriptionWebView loadHTMLString:self.mediaTypeLongDescription baseURL:nil];

该表只需要两种类型的单元格。有一个没有附件的单元格包含 Web 视图 (longDescriptionCell),表格的其余部分包含包含带有披露指示器附件的简单文本字符串 (mediaTypeCell) 的单元格。

所以...我们应该从哪里开始...?

通常,在单元格中使用UIBewView(UIrScrollView)不是一个好主意。但这并非不可能,你只需要关心它,所以,如果你只是想学习如何使用表格,你可以从更简单的东西开始......

顺便说一下,你正在犯的更大的错误:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// (..)
       if (!cell) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierLongDescription];
        }
        [cell.contentView addSubview:self.longDescriptionWebView];
// (..)
} 
每次表需要显示单元格时都会

使用和调用此协议方法,因此它在第一次显示(对于每个单元格)以及用户向下和向上滚动时运行。

表格的魔力是重用屏幕外上升的单元格(如果用户向下滚动),以在向下数据所需的新数据中重复使用同一单元格。

这就是你应该问这样的事情的方式:

   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierMediaType];

该代码只是询问是否有未使用的单元格可用于新的所需数据。此时,如果它不存在,我们需要分配一个新的并设置它的对象以显示正确的数据。

但是如果它存在,我们不需要分配一个新的(这就是你正在做的,好的)并且我们应该在其中添加新对象(或者如果我们这样做,我们应该删除其中的旧对象)

每次滚动时,您都会添加一个 Web 视图,将其添加到旧视图上,如下所示:

       [cell.contentView addSubview:self.longDescriptionWebView];

这是一个很大的错误,您应该重用旧的webView,告诉它加载一个新的HTML页面(或您在其中显示的其他内容)

还有一件事:当您使用

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierMediaType];

您请求具有 id 的现有单元格 单元格标识符媒体类型

但随后您询问并使用不同的 id 单元格(CellIdentifierLongDescription)

最新更新