无限滚动UITableView在从服务器检索数据后向上滚动时会出现故障

时间:2015-01-30 11:17:43

标签: ios uitableview swift

我有一个源自服务器的15个帖子。当我在列表结尾之前向下滚动到3时,我会在服务器上ping下15个帖子。此功能非常有用。然而,当我开始向上滚动时,UITableViewCells经常跳起来,好像Cell 5现在正在填充Cell 4,而Cell 4现在正在填充Cell 3等。要么就是这样,要么UITableView滚动只是跳起来。

当我到达UITableView的顶部,然后继续向下滚动我的所有数据然后备份,它完美地工作。我的桌子有绘图问题吗?

编辑:所以,我发现这种情况正在发生,因为我所有细胞的高度都是动态的。我非常确定当我向上滚动时,我的UITableView正在计算并设置适当的高度,这会导致跳跃动作。我不确定如何减轻这种情况。

2 个答案:

答案 0 :(得分:0)

我从未在iOS8中使用动态单元格大小的新功能,但我可以为您提供一些提高表格视图性能的建议。它应该是一个评论,但它不适合。

  • 如果可以,请缓存已显示的单元格的高度。一个简单的字典与一种id匹配就可以解决问题
  • 请注意,您单元的子视图之间没有复杂的布局
  • 检查是否正在绘制需要屏幕外渲染的内容,例如角半径,裁剪等

我不知道动态单元在ios8上是如何工作的,但我分享了我的代码。这很简单。我有一个用作原型的单元格,每次我需要计算一个单元格高度我用它的数据提供它,我强迫它的布局让我得到正确的高度。一旦我获得了高度,我就将它保存在NSDictionary中,使用postID(它是一个类似app的app)作为密钥。
只有在未缓存单元格高度时才会发生这种情况。如果它被缓存,则返回高度。

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGSize  size = CGSizeZero;
    NSDictionary * data = self.timelineData[indexPath.row];
    if (data[KEY_CELL_IDENTIFIER] == CellIdentifierPost) {
        NSNumber * cachedHeight = [self.heightCaches objectForKey:@([(AFTimelinePostObject*)data[KEY_CELL_DATA] hash])];//[(AFTimelinePostObject*)data[KEY_CELL_DATA] timelinePostObjectId]];
        if (cachedHeight) {
            return (CGFloat)[cachedHeight doubleValue];
        }
        [_heightCell configureCellWith:data[KEY_CELL_DATA]];
        size = [_heightCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        [self.heightCaches setObject:@(size.height) forKey:@([(AFTimelinePostObject*)data[KEY_CELL_DATA] hash])];//[(AFTimelinePostObject*)data[KEY_CELL_DATA] timelinePostObjectId]];
    }
    else if (data[KEY_CELL_IDENTIFIER] == CellIdentifierComment){
        NSNumber * cachedHeight = [self.heightCaches objectForKey:@([(AFTimelinePostComments*)data[KEY_CELL_DATA] hash])];//[(AFTimelinePostObject*)data[KEY_CELL_DATA] timelinePostObjectId]];
        if (cachedHeight) {
            return (CGFloat)[cachedHeight doubleValue];
        }
        [_heightCommentCell configureCellWith:data[KEY_CELL_DATA]];
        size = [_heightCommentCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        if (size.height < 80.0f) {
            size = (CGSize) {
                .width = NSIntegerMax,
                .height = 115.f
            };
        }
        else if (size.height > 180.0f) {
            size = (CGSize) {
                .width = NSIntegerMax,
                .height = 180.f
            };
        }

        [self.heightCaches setObject:@(size.height) forKey:@([(AFTimelinePostComments*)data[KEY_CELL_DATA] hash])];//[(AFTimelinePostObject*)data[KEY_CELL_DATA] timelinePostObjectId]];

    }
    else {
        size = (CGSize) {
            .width = NSIntegerMax,
            .height = 50.f
        };
    }

    return size.height;
}

答案 1 :(得分:0)

不幸的是,似乎没有一个简单的答案。我在多个iOS应用程序上一直在努力。

我找到的唯一解决方案是再次出现时以编程方式滚动到UITableView的顶部。

[self.tableView setContentOffset:CGPointMake(0, 0 - self.tableView.contentInset.top) animated:YES];

OR

self.tableView.contentOffset = CGPointMake(0, 0 - self.tableView.contentInset.top);

希望这是一个可以接受的工作,同时仍能使用动态单元格高度=)