问题描述
iOS开发中,可能会在纵向tableView的cell中嵌套collectionView,而横向collectionView滑动后会发生偏移,若从其他页面返回该页面重新刷新列表时,会产生不同程度的偏移,测试可能会描述为列表弹动。
原因分析
纵向列表中的每一项都嵌套了一个横向列表,横向列表滚动产生偏移,列表刷新时从复用池随机选择一个横向列表进行数据填充,每个项的偏移不同,又是随机选择,产生了视觉上的弹动。这是列表复用机制产生的副作用。
解决方案
- 增加可见横向列表的偏移量缓存,在视图已经消失的时候,将可见的cell的collectionView的偏移量缓存起来,在需要返回cell的时候,重新设置collectionView偏移量
- 区别较大的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;//用完清除
}
}
这个处理方案,既保留了复用性,保证了性能,又处理了复用问题,保证了用户体验。