UITableView длительность анимации строки и обратный вызов завершения - PullRequest
95 голосов
/ 30 сентября 2010

Есть ли способ указать продолжительность анимации строк UITableView или получить обратный вызов после завершения анимации?

То, что я хотел бы сделать, это мигать индикаторами прокрутки после завершения анимации. Делать вспышку до этого ничего не значит. До сих пор у меня есть обходной путь - задержка на полсекунды (это похоже на продолжительность анимации по умолчанию), т.е.

[self.tableView insertRowsAtIndexPaths:newRows
                      withRowAnimation:UITableViewRowAnimationFade];
[self.tableView performSelector:@selector(flashScrollIndicators)
                     withObject:nil
                     afterDelay:0.5];

Ответы [ 7 ]

195 голосов
/ 24 октября 2012

только что с этим сталкивался. Вот как это сделать:

Objective-C

[CATransaction begin];
[tableView beginUpdates];
[CATransaction setCompletionBlock: ^{
    // Code to be executed upon completion
}];
[tableView insertRowsAtIndexPaths: indexPaths
                 withRowAnimation: UITableViewRowAnimationAutomatic];
[tableView endUpdates];
[CATransaction commit];

Swift

CATransaction.begin()
tableView.beginUpdates()
CATransaction.setCompletionBlock {
    // Code to be executed upon completion
}
tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
tableView.endUpdates()
CATransaction.commit()
39 голосов
/ 31 августа 2013

Расширяя точный ответ Карвага , обратите внимание, что в iOS 7 окружение транзакции CAT анимацией UIView обеспечивает контроль длительности анимации таблицы.

[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.

25 голосов
/ 25 апреля 2014

Сокращение Прекрасный ответ Брента , по крайней мере для iOS 7 вы можете кратко обернуть все это в [UIView animateWithDuration: delay: options: animations: complete:] call:

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

хотя я не могу переопределить кривую анимации по умолчанию из чего-либо, кроме EaseInOut.

23 голосов
/ 27 января 2017

Это чертовски полезный трюк!Я написал расширение UITableView, чтобы не писать вещи CATransaction постоянно.

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)
        })
23 голосов
/ 05 февраля 2016

Вот Swift-версия ответа Карвага

    CATransaction.begin()
    tableView.beginUpdates()
    CATransaction.setCompletionBlock { () -> Void in
        // your code here
    }
    tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
    tableView.endUpdates()
    CATransaction.commit()
6 голосов
/ 18 марта 2015

Для меня это нужно было для collectionView. Я сделал простое расширение, чтобы решить это:

extension UICollectionView {

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

        self.reloadSections(sections)

        CATransaction.commit()
    }

}
0 голосов
/ 01 октября 2010

Вы можете попытаться обернуть insertRowsAtIndexPath в

- (void)beginUpdates
- (void)endUpdates

транзакция, затем сделайте флеш.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...