programing tip

UITableView 행 애니메이션 기간 및 완료 콜백

itbloger 2020. 8. 26. 07:38
반응형

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에서 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 수준에서 다르게 구현됩니다.


Shortening Brent's fine answer, for at least iOS 7 you can wrap this all tersely in a [UIView animateWithDuration:delay:options:animations:completion:] call:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  [self.tableView beginUpdates];
  [self.tableView endUpdates];
} completion:^(BOOL finished) {
  // completion code
}];

though, I can't seem to override the default animation curve from anything other than EaseInOut.


That's one hell of a useful trick! I wrote a UITableView extension to avoid writing CATransaction stuff all the time.

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()
    }

}

This is used like so:

// 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)
        })

Here's a Swift version of karwag's answer

    CATransaction.begin()
    tableView.beginUpdates()
    CATransaction.setCompletionBlock { () -> Void in
        // your code here
    }
    tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
    tableView.endUpdates()
    CATransaction.commit()

For me I needed this for a collectionView. I've made a simple extension to solve this:

extension UICollectionView {

    func reloadSections(sections: NSIndexSet, completion: () -> Void){
        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)

        self.reloadSections(sections)

        CATransaction.commit()
    }

}

You could try to wrap the insertRowsAtIndexPath in a

- (void)beginUpdates
- (void)endUpdates

transaction, then do the flash afterwards.

참고URL : https://stackoverflow.com/questions/3832474/uitableview-row-animation-duration-and-completion-callback

반응형