处理iOS列表嵌套,滚动子列表后,返回刷新该列表,子列表会发生偏移

问题描述

iOS开发中,可能会在纵向tableView的cell中嵌套collectionView,而横向collectionView滑动后会发生偏移,若从其他页面返回该页面重新刷新列表时,会产生不同程度的偏移,测试可能会描述为列表弹动。

原因分析

纵向列表中的每一项都嵌套了一个横向列表,横向列表滚动产生偏移,列表刷新时从复用池随机选择一个横向列表进行数据填充,每个项的偏移不同,又是随机选择,产生了视觉上的弹动。这是列表复用机制产生的副作用。

解决方案

  1. 增加可见横向列表的偏移量缓存,在视图已经消失的时候,将可见的cell的collectionView的偏移量缓存起来,在需要返回cell的时候,重新设置collectionView偏移量
  2. 区别较大的cell应使用不同的复用id

第2点就不用多说了,下面对第1点给出代码示例

界面消失时,缓存可见cell的偏移量

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    // 放在这里是 减少计算,如果不行,放到viewWillDisappear:(BOOL)animated
    [self.collectionViewOffsets removeAllObjects];
    // 获取可见的cell
    [[self.tableView visibleCells] enumerateObjectsUsingBlock:^(__kindof UGCinemaDiscoverCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj isKindOfClass:UGCinemaDiscoverCell.class]){
            // 获取当前cell的索引
            NSIndexPath *index = [self.tableView indexPathForCell:obj];
            if (index) {
                self.collectionViewOffsets[index] = [NSValue valueWithCGPoint:obj.collectionView.contentOffset];
            }
        }
    }];
}

返回cell时,重新设置偏移量

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UGCinemaDiscoverCell *cell = [tableView dequeueReusableCellWithIdentifier:UGCinemaDiscoverCell.reuseID];
    NSValue * offset = self.collectionViewOffsets[indexPath];
    if (offset){
        cell.collectionView.contentOffset = offset.CGPointValue;
        self.collectionViewOffsets[indexPath] = nil;//用完清除
    }
}

这个处理方案,既保留了复用性,保证了性能,又处理了复用问题,保证了用户体验。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容