如何在UITableView beginUpdates/endUpdates上检测到该动画已结束?

pix*_*eak 114 iphone objective-c ipad ios

我正在使用insertRowsAtIndexPaths/deleteRowsAtIndexPaths包装插入/删除表格单元格beginUpdates/endUpdates.beginUpdates/endUpdates调整rowHeight时我也在使用.默认情况下,所有这些操作都是动画的.

使用时如何检测动画已结束beginUpdates/endUpdates

Rud*_*vič 289

那这个呢?

[CATransaction begin];

[CATransaction setCompletionBlock:^{
    // animation has finished
}];

[tableView beginUpdates];
// do some work
[tableView endUpdates];

[CATransaction commit];
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为tableView CALayer动画在内部使用动画.也就是说,他们将动画添加到任何开放状态CATransaction.如果不CATransaction存在open (正常情况),则隐式地开始一个,这在当前runloop的结尾处结束.但如果你自己开始,就像在这里完成一样,那么它将使用那个.

  • 不适合我.在动画仍在运行时调用完成块. (7认同)
  • 如果单元格包含带动画的视图,即UIActivityIndi​​catorView,则永远不会调用完成块. (6认同)
  • 经过这么久,我从来不知道这一点.纯金 !!没有什么比看到一个漂亮的动画被必要的tableView.reloadData()邪恶杀死更糟糕的了. (3认同)
  • @MrVincenzo您是否在片段中的`beginUpdates`和`endUpdates`之前设置了`completionBlock`? (2认同)
  • `[CATransaction commit]`应该在`[tableView endUpdates]`之前调用. (2认同)
  • 我再试一次,它完美无缺.谢谢. (2认同)

Mic*_*ael 28

Swift版本


CATransaction.begin()

CATransaction.setCompletionBlock({
    do.something()
})

tableView.beginUpdates()
tableView.endUpdates()

CATransaction.commit()
Run Code Online (Sandbox Code Playgroud)


Rob*_*ert 7

如果您的目标是 iOS 11 及更高版本,则应UITableView.performBatchUpdates(_:completion:)改用:

tableView.performBatchUpdates({
    // delete some cells
    // insert some cells
}, completion: { finished in
    // animation complete
})
Run Code Online (Sandbox Code Playgroud)


Ant*_*oni 5

一个可能的解决方案可能是从您调用的 UITableView 继承endUpdates并覆盖其setContentSizeMethod,因为 UITableView 会调整其内容大小以匹配添加或删除的行。这种方法也应该适用于reloadData.

为了确保只有在endUpdates被调用后才发送通知,还可以覆盖endUpdates并在那里设置一个标志。

// somewhere in header
@private BOOL endUpdatesWasCalled_;

-------------------

// in implementation file

- (void)endUpdates {
    [super endUpdates];
    endUpdatesWasCalled_ = YES;
}

- (void)setContentSize:(CGSize)contentSize {
    [super setContentSize:contentSize];

    if (endUpdatesWasCalled_) {
        [self notifyEndUpdatesFinished];
        endUpdatesWasCalled_ = NO;
    }
}
Run Code Online (Sandbox Code Playgroud)


Zde*_*nek 5

您可以将操作包含在UIView动画块中,如下所示:

- (void)tableView:(UITableView *)tableView performOperation:(void(^)())operation completion:(void(^)(BOOL finished))completion
{
    [UIView animateWithDuration:0.0 animations:^{

        [tableView beginUpdates];
        if (operation)
            operation();
        [tableView endUpdates];

    } completion:^(BOOL finished) {

        if (completion)
            completion(finished);
    }];
}
Run Code Online (Sandbox Code Playgroud)

致积于/sf/answers/903358011/.

  • 这段代码对我不起作用.完成块在`endUpdates`之后调用,但是在动画完成之前. (4认同)