UITableView行アニメーションの期間を指定する方法、またはアニメーションが完了したときにコールバックを取得する方法はありますか?
私がやりたいのは、アニメーションが完了した後にスクロールインジケータを点滅させることです。それより前にフラッシュを実行しても、何も実行されません。これまでのところ、私が持っている回避策は0.5秒を遅らせることです(これはデフォルトのアニメーション持続時間のようです)、すなわち:
[self.tableView insertRowsAtIndexPaths:newRows
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView performSelector:@selector(flashScrollIndicators)
withObject:nil
afterDelay:0.5];
これに出会ったばかりです。方法は次のとおりです。
Objective-C
[CATransaction begin];
[tableView beginUpdates];
[CATransaction setCompletionBlock: ^{
// Code to be executed upon completion
}];
[tableView insertRowsAtIndexPaths: indexPaths
withRowAnimation: UITableViewRowAnimationAutomatic];
[tableView endUpdates];
[CATransaction commit];
スイフト
CATransaction.begin()
tableView.beginUpdates()
CATransaction.setCompletionBlock {
// Code to be executed upon completion
}
tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
tableView.endUpdates()
CATransaction.commit()
karwag's fine answer を展開すると、iOS 7では、CATransactionをUIView Animationで囲んで、テーブルアニメーションの長さを制御できます。
[UIView beginAnimations:@"myAnimationId" context:nil];
[UIView setAnimationDuration:10.0]; // Set duration here
[CATransaction begin];
[CATransaction setCompletionBlock:^{
NSLog(@"Complete!");
}];
[myTable beginUpdates];
// my table changes
[myTable endUpdates];
[CATransaction commit];
[UIView commitAnimations];
UIViewアニメーションの継続時間は、iOS 6には影響しません。おそらく、iOS 7のテーブルアニメーションは、UIViewレベルで異なる方法で実装されます。
短縮 Brent's fine answer 、少なくともiOS 7では、これを[UIView animateWithDuration:delay:options:animations:completion:]呼び出しで簡潔にラップできます:
[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[self.tableView beginUpdates];
[self.tableView endUpdates];
} completion:^(BOOL finished) {
// completion code
}];
ただし、EaseInOut以外の既定のアニメーションカーブをオーバーライドすることはできません。
これは便利なトリックの1つの地獄です!常にCATransactionを記述することを避けるために、UITableView拡張を作成しました。
import UIKit
extension UITableView {
/// Perform a series of method calls that insert, delete, or select rows and sections of the table view.
/// This is equivalent to a beginUpdates() / endUpdates() sequence,
/// with a completion closure when the animation is finished.
/// Parameter update: the update operation to perform on the tableView.
/// Parameter completion: the completion closure to be executed when the animation is completed.
func performUpdate(_ update: ()->Void, completion: (()->Void)?) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
// Table View update on row / section
beginUpdates()
update()
endUpdates()
CATransaction.commit()
}
}
これは次のように使用されます。
// Insert in the tableView the section we just added in sections
self.tableView.performUpdate({
self.tableView.insertSections([newSectionIndex], with: UITableViewRowAnimation.top)
}, completion: {
// Scroll to next section
let nextSectionIndexPath = IndexPath(row: 0, section: newSectionIndex)
self.tableView.scrollToRow(at: nextSectionIndexPath, at: .top, animated: true)
})
Swift karwag's answer =のバージョン
CATransaction.begin()
tableView.beginUpdates()
CATransaction.setCompletionBlock { () -> Void in
// your code here
}
tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
tableView.endUpdates()
CATransaction.commit()
私にとっては、collectionViewにこれが必要でした。これを解決するために簡単な拡張を行いました。
extension UICollectionView {
func reloadSections(sections: NSIndexSet, completion: () -> Void){
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.reloadSections(sections)
CATransaction.commit()
}
}