首页 > 解决方案 > UITableView scrollToRowAtIndexPath 不会触发 scrollViewDidEndScrollingAnimation

问题描述

我的代码想要reloadData在滚动动画完成后推迟调用。

  1. 当数据源更新performNextUpdate时将被调用。
  2. performNextUpdate只会在它不播放滚动动画的情况下。
  3. 调用后reloadData,我最后调用scrollToRowAtIndexPath单元格来播放滚动动画。
  4. 我知道didEndScrollingAnimation如果单元格已经在它应该滚动到的位置,它将不会被触发。所以我必须canScrollToBottomAtIndexPath检查。
  5. 滚动动画完成后,我将performNextUpdate再次调用 from pendingDataSource(如果存在)。

我的问题是,很少scrollViewDidEndScrollingAnimation不触发。所以animateScrolling = YES,永远。即使有pendingDataSource,该应用程序也将不再reloadData

有谁知道scrollViewDidEndScrollingAnimation打电话时没有触发的原因是什么scrollToRowAtIndexPath:


这是我的示例代码,

- (void)performNextUpdate {
    if (self.pendingDataSource && !self.animateScrolling) {
        self.dataSource = self.pendingDataSource;
        [self.tableView reloadData];
        [self animateScrollToBottomIfNeeded];
    }
}

- (void)animateScrollToBottomIfNeeded {
    if ([self canScrollToBottomAtIndexPath:indexPath]) {
        self.animateScrolling = YES;
        [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        // Wait for didEndScrollingAnimation to call before performing the next update
    } else {
        // Can perform the next update immediately, since there's no need to scroll.
        self.animateScrolling = NO;
        [self performNextUpdate];
    }
}

// Sometimes this function is not triggered. 
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    self.animateScrolling = NO;
    [self performNextUpdate];
}

- (BOOL)canScrollToBottomAtIndexPath:(NSIndexPath *)indexPath {
    if (!indexPath) {
        return NO;
    }
    if ((self.tableView.tracking || self.tableView.dragging) && !self.tableView.isDecelerating) {
        return NO;
    }
    CGRect viewPort = CGRectMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y, self.tableView.bounds.size.width, self.tableView.bounds.size.height);
    CGRect visibleViewPort = UIEdgeInsetsInsetRect(viewPort, self.tableView.contentInset);
    CGRect cellRect = [self.tableView rectForRowAtIndexPath:indexPath];
    if (CGRectEqualToRect(cellRect, CGRectZero)) {
        // If indexPath is invalid, it will return CGRectZero.
        return NO;
    } else {
        return !CGRectContainsRect(visibleViewPort, cellRect);
    }
}

标签: iosuitableviewuiscrollview

解决方案


推荐阅读