UITableView与行中的UICollectionView同时在不同的行中滚动怪异滚动

时间:2018-04-14 09:19:41

标签: ios uitableview uicollectionview

我们有一个UITableView,每行UICollectionView支持horizontal scroll,但未启用paging

我们已注册要重复使用的单元格,

    // Setup for VenueFilterTableViewCell
    NSString * cellIdentifier = @"VenueFilterTableViewCell";
    VenueFilterTableViewCell *tbCell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (tbCell == nil) {
        tbCell = [[VenueFilterTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                                 reuseIdentifier:cellIdentifier];
        tbCell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    // Method for inflate the UICollectionView in the row
    [tbCell setVenues:venues
              loading:NO
           atLocation:self.definedLocation
     forFilter:filter
         withDelegate:self];
    cell = tbCell;

当我在UICollectionView的{​​{1}} 0处indexPath.row水平滚动行时,UITableViewCell 3(最初在屏幕外)同时滚动。因此,如果在滚动水平后,您可以快速向下滚动,您可以看到第3行,第7行......依此类推,同时滚动。

我在每个单元格中都有一个进度条,用于向用户提供反馈到他的水平滚动结束的距离,但由于这种重用行为,所涉及的每一行(0和3和7)都搞乱了对方的进展。

有什么建议吗?

更新

我在indexPath.row中添加了下一个事件,用于控制单元格何时离开屏幕并强制UITableView内部停止滚动。这增强了一点性能,但最终问题再次发生。

UICollectionView中的代码,用于检测行何时不在屏幕上:

UITableViewController

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if ([tableView.indexPathsForVisibleRows indexOfObject:indexPath] == NSNotFound) { // This indeed is an indexPath no longer visible // Do something to this non-visible cell... if ([cell isKindOfClass:[VenueFilterTableViewCell class]]) { VenueFilterTableViewCell *tbCell = (VenueFilterTableViewCell *) cell; [tbCell stopScrolling]; } } } 中包含UITableViewCell视图的代码,在重新加载内容中,除了恢复contentOffset之外,我们还需要重新启用UICollection

self.collectionView.scrollEnabled = YES;

2 个答案:

答案 0 :(得分:1)

我的第一个回答没有帮助。所以我已经解决了这个问题很抱歉把它放在swift中你可以很容易地在objc中转换它

我已经使用以下代码实现了willDisplayCell和endDispayCell

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    guard let cell = cell as? ScreenShotsCell else { return }
    self.configureCell(for: indexPath, to: cell)
    cell.collectionView.setContentOffset(cell.collectionView.contentOffset, animated: true)
    cell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
}

//--------------------------------------------------------------------------------

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    guard let cell = cell as? ScreenShotsCell else { return }
    storedOffsets[indexPath.row] = cell.collectionViewOffset
    cell.collectionView.setContentOffset(cell.collectionView.contentOffset, animated: true)
}

主要核心逻辑是cell.collectionView.setContentOffset所以当它不可见时它将停止滚动,因此它将修复由于重用单元格而导致其他行的tableview滚动的问题

希望它有用

答案 1 :(得分:0)

似乎是由单元重用引起的典型问题。如果您确实有UICollectionView作为单元格的一部分,最好的方法是创建Dictionary存储的偏移量

简单示例:

var storedOffsets: [Int: CGFloat] = [:]

tableView:didEndDisplaying:forRowAt:中存储 collectionView&#39> contentOffset的偏移量。

然后在tableView:willDisplay:forRowAt:中使用这些存储的偏移设置单元格中contentOffset的{​​{1}}。