UITableView 动画在部分之间滚动,同时临时删除过多的单元格以简化动画

Posted

技术标签:

【中文标题】UITableView 动画在部分之间滚动,同时临时删除过多的单元格以简化动画【英文标题】:UITableView animated scrolling between sections while temporarily removing excessive cells for simplified animation 【发布时间】:2012-11-03 16:39:33 【问题描述】:

在我们的应用程序中,用户可以使用表格视图之外的一些控件以直观的方式滚动到表格视图中的下一部分。某些部分包含许多单元格,并且滚动动画看起来不流畅,因为要滚动的单元格太多。为了制作简单易懂的动画,我们希望暂时删除动画中多余的单元格。

说用户正在使用

section.0 row.5 out of 100 rows

他想滚动到

section.1 row.0 out of 100 rows

然后我们想要在滚动动画时跳过所有多余的单元格。所以我们暂时要删除之间的所有单元格

e.g. section.0 row.10 untill section.0 row.98

有什么想法可以解决这个问题吗?我相信这对其他人也可能有用。我想尽可能干净地做到这一点。

【问题讨论】:

您是重复使用单元格还是每个单元格都是独一无二的? 我正在重用单元格。会有所不同吗? 您也许可以使用可重复使用的外观单元,只需在您要制作动画的位置重新加载数据。 似乎是个好主意。但我更感兴趣的是了解如何设置整个系统。我添加了一个尝试作为答案,但我不确定这是否是要走的路.. 【参考方案1】:

我有一些关于如何处理这个问题的想法。首先是重新加载感兴趣的单元格,并返回一个轻量级单元格。您也许可以使用CGBitmapContext 将图像数据复制到“外观”单元格而不是真实单元格中。其次是重新加载UITableView 的数据,然后不返回感兴趣行的数据。第三是实际删除行。另一个想法可能是在制作动画时禁用交互。

重新加载行:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

插入/删除行:

[tableView beginUpdate];
[tableView insertRowsAtIndexPaths:*arrayOfIndexPaths* withRowAnimation:*rowAnimation*];
[tableView endUpdate];

[tableView beginUpdate];
[tableView deleteRowsAtIndexPaths:*arrayOfIndexPaths* withRowAnimation:*rowAnimation*];
[tableView endUpdate];

禁用交互:

[UIApplication sharedApplication] beginIgnoringInteractionEvents];

【讨论】:

【参考方案2】:

这是一个早期的尝试。我觉得这有点乱..

Self 是 UITableView 的子类

- (void)scrollAndSkipCellsAnimatedToTopOfSection:(NSUInteger)section

    CGRect sectionRect = [self rectForHeaderInSection:section];
    CGPoint targetPoint = sectionRect.origin;
    CGFloat yOffsetDiff = targetPoint.y - self.contentOffset.y;
    BOOL willScrollUpwards = yOffsetDiff > 0;

    if(willScrollUpwards)
    
        [self scrollAndSkipCellsAnimatedUpwardsWithDistance:fabs(yOffsetDiff)];
    
    else
    
        [self scrollAndSkipCellsAnimatedDownwardsWithDistance:fabs(yOffsetDiff)];
    


- (void)scrollAndSkipCellsAnimatedUpwardsWithDistance:(CGFloat)distance

    // when going upwards contentOffset should decrease

    CGRect rectToRemove = CGRectMake(0,
                             self.contentOffset.y + (self.bounds.size.height * 1.5) - distance,
                             self.bounds.size.width,
                             distance - (self.bounds.size.height * 2.5));

    BOOL shouldRemoveAnyCells = rectToRemove.size.height > 0;

    if(shouldRemoveAnyCells)
    
        // property on my subclass of uitableview
        // these indexes may span over several sections
        self.tempRemoveIndexPaths = [self indexPathsForRowsInRect:rectToRemove];
    

    [UIView setAnimationsEnabled:NO];
    [self beginUpdates];
    [self deleteRowsAtIndexPaths:self.tempRemoveIndexPaths withRowAnimation:UITableViewRowAnimationNone];
    [self endUpdates];
    [UIView setAnimationsEnabled:YES];

    [self setContentOffset:CGPointMake(0, self.contentOffset.y - distance) animated:YES];


// And then I would probably have to put some logic into
// - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;


- (void)scrollAndSkipCellsAnimatedDownwardsWithDistance:(CGFloat)distance



【讨论】:

以上是关于UITableView 动画在部分之间滚动,同时临时删除过多的单元格以简化动画的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UITableView 在同时滚动和更新时会丢失部分标题?

iOS11 中奇怪的 uitableview 行为。单元格通过导航推送动画向上滚动

UITableView 滚动时动画单元格

UITableView, setContentOffset 动画:NO 不会在 iPad 上滚动

当 UITableView 开始滚动时,动画视图

UITableView 视差标题滚动动画(TuneIn)