UITableView 행 애니메이션 기간 및 완료 콜백
UITableView 행 애니메이션의 기간을 지정하거나 애니메이션이 완료되면 콜백을 받을 수 있는 방법이 있습니까?
제가 하고 싶은 것은 애니메이션이 완료된 후 스크롤 표시기를 깜박이는 것입니다.그 전에 플래시를 하는 것은 아무 효과가 없습니다.지금까지 해결 방법은 0.5초 지연하는 것입니다(기본 애니메이션 기간인 것 같습니다). 즉,
[self.tableView insertRowsAtIndexPaths:newRows
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView performSelector:@selector(flashScrollIndicators)
withObject:nil
afterDelay:0.5];
우연히 발견했어요.방법은 다음과 같습니다.
목표-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의 훌륭한 답변을 확장하면, iOS 7에서 UIView 애니메이션으로 CAT 트랜잭션을 둘러싸면 테이블 애니메이션 기간을 제어할 수 있습니다.
[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 수준에서 다르게 구현될 것입니다.
그건 정말 유용한 속임수야!저는 항상 CAT 트랜잭션 항목을 작성하지 않기 위해 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)
})
적어도 iOS 7에 대해서는 브렌트의 훌륭한 답변을 요약하면, 당신은 이 모든 것을 [UIview animateWithDuration:delay:options:애니메이션:completion:] 통화로 마무리할 수 있습니다.
[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[self.tableView beginUpdates];
[self.tableView endUpdates];
} completion:^(BOOL finished) {
// completion code
}];
하지만, 저는 EasyInOut 이외의 다른 것에서 기본 애니메이션 곡선을 재정의할 수 없습니다.
여기 카와그의 대답의 스위프트 버전이 있습니다.
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()
}
}
요즘 당신이 이것을 하고 싶다면 iOS 11부터 새로운 기능이 있습니다.
- (void)performBatchUpdates:(void (^)(void))updates
completion:(void (^)(BOOL finished))completion;
업데이트 마감 시 beginUpdates()/endUpdates 섹션과 동일한 코드를 배치합니다.그리고 완성은 모든 애니메이션이 끝난 후에 실행됩니다.
표 보기performBatch메소드는 iOS 11부터만 사용할 수 있으며, 다음 확장자를 사용할 수 있습니다.
extension UITableView {
func performUpdates(_ updates: @escaping () -> Void, completion: @escaping (Bool) -> Void) {
if #available(iOS 11.0, *) {
self.performBatchUpdates({
updates()
}, completion: completion)
} else {
CATransaction.begin()
beginUpdates()
CATransaction.setCompletionBlock {
completion(true)
}
updates()
endUpdates()
CATransaction.commit()
}
}
}
Antoine의 답변은 매우 좋지만 UICollectionView에 대한 답변입니다.UITableView에 대한 내용은 다음과 같습니다.
extension UITableView {
func reloadSections(_ sections: IndexSet, with rowAnimation: RowAnimation, completion: (() -> Void)?) {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
self.reloadSections(sections, with: rowAnimation)
CATransaction.commit()
}
}
다음과 같이 부릅니다.
tableView.reloadSections(IndexSet(0), with: .none, completion: {
// Do the end of animation thing
})
tableView가 UIView.animate의 애니메이션 매개 변수를 무시하고 "위에서 아래로" 기본 애니메이션을 사용하여 행을 다시 로드할 때 문제가 발생하는 경우 다음과 같은 이상한 해결책을 발견했습니다.
필요한 작업:
- 사일런트 테이블애니메이션 보기
- 전환 애니메이션을 대신 사용
예:
let indicesToUpdate = [IndexPath(row: 1, section: 0)]
UIView.transition(with: self.tableView,
duration: 0.5,
options: [.transitionCrossDissolve,
.allowUserInteraction,
.beginFromCurrentState],
animations: {
UIView.performWithoutAnimation {
self.tableView.reloadRows(at: indicesToUpdate,
with: .none)
}
})
PS: UIView.transition(...)에도 옵션 완료가 있습니다. :)
insertRowsAtIndexPath를 다음과 같이 랩핑할 수 있습니다.
- (void)beginUpdates
- (void)endUpdates
트랜잭션을 수행한 다음 플래시를 수행합니다.
언급URL : https://stackoverflow.com/questions/3832474/uitableview-row-animation-duration-and-completion-callback
'programing' 카테고리의 다른 글
| Sinatra로 정적 파일 제공 (0) | 2023.06.03 |
|---|---|
| Git 하위 모듈과 하위 트리 간의 차이 (0) | 2023.06.03 |
| Git에서 로컬 커밋을 폐기하는 방법은 무엇입니까? (0) | 2023.06.03 |
| rvm 설치가 작동하지 않음: "RVM이 함수가 아닙니다." (0) | 2023.06.03 |
| 속성에 대한 바인딩 상태에 대한 [(ngModel)]과 [ngModel]의 차이점은 무엇입니까? (0) | 2023.06.03 |