我有可能看起来像一个非常奇怪的问题(它对我有用!)
我使用UITableView
来显示每个包含UIWebView
的单元格。我意识到这是一个坏主意,但我不能以任何其他方式做到这一点。
我在UIWebView
完成加载后缓存每个单元格的高度,然后调用:
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[cellIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
所有密码均为in a Gist here。
我还将UIWebView
缓存在数据源的字典中,因此可以在重新加载单元格时重复使用它。
这似乎有点工作,但我遇到很多问题,细胞的内容会随机消失。我添加了一些日志记录来确定发生了什么,以什么顺序,似乎有些单元格正在重复使用,而它们仍然在屏幕上。
我向下滚动时会在日志中看到这一点:
2014-02-11 13:45:49.091 EApp[45936:70b] Generating cell for 1: Panning
2014-02-11 13:45:49.245 EApp[45936:70b] Generating cell for 2: Calibration
2014-02-11 13:45:50.063 EApp[45936:70b] Generating cell for 3: Aperture Priority
2014-02-11 13:45:50.063 EApp[45936:70b] Reusing cell: Stopping down
在这种情况下,“停止”是仍在屏幕上的单元格。 “生成单元格”项目记录在数据源的cellForRowAtIndexPath
内,并在单元格prepareForReuse
内记录“重复使用”消息。
有谁知道这里会发生什么?我知道这似乎很复杂。
答案 0 :(得分:1)
prepareForReuse
中的以下行可能是罪魁祸首:
if ([self.contentWebView isDescendantOfView:self.contentWebView]) {
[self.contentWebView removeFromSuperview];
}
由于contentWebView
永远不是自身的后代,因此不会从单元格中移除它,并且contentView将包含 两个 webview {1}}:
你可能想说:
cellForRowAtIndexPath
或者简单地说:
if ([self.contentWebView isDescendantOfView:self.contentView]) {
[self.contentWebView removeFromSuperview];
}
答案 1 :(得分:0)
UITableView的一个特性/限制是您不知道是否,也不能依赖于正在创建或重用的单元格。你应该始终能够处理这两个问题。
GENERALLY ,当您调用-reloadRowsAtIndexPaths:withRowAnimation:
时,您将从该indexPath获取要重用的单元格。如果该indexPath在屏幕上,它将是屏幕上的一个单元格。
答案 2 :(得分:0)
我不知道这是不是问题,但是在您提供的代码中,您甚至没有初始化您的单元格...
我甚至对此感到惊讶。
static NSString *CellIdentifier = @"FeedItemCell";
EFeedItemCell *cell = [self.tableViewController.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
你应该添加它:
if (!cell) {
cell = [EfeedItemCell alloc] initWithReus....];
}
答案 3 :(得分:0)
从您的代码中,您似乎正在缓存webViews,然后以编程方式将它们添加到单元格中。这可能会产生类似于我在传递过程中遇到的随机问题。
您必须在故事板中使用 EFeedItemCellWebView
。只需添加UIWebView
并将类名更改为自定义类。然后在加载数据时,只需在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;