UICollectionView анимировать изменение данных



в моем проекте я использую UICollectionView для отображения сетки иконок.



пользователь может изменить порядок, щелкнув сегментированный элемент управления, который вызывает выборку из основных данных с помощью другого NSSortDescriptor.



объем данных всегда один и тот же, просто в конечном итоге в разных разделах / строках:



- (IBAction)sortSegmentedControlChanged:(id)sender {

_fetchedResultsController = nil;
_fetchedResultsController = [self newFetchResultsControllerForSort];

NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}

[self.collectionView reloadData];
}


проблема в том, что reloadData не анимирует изменение, UICollectionView просто появляется с новым данные.



должен ли я отслеживать, в каком indexPath ячейка была до и после изменения, и использовать [self.collectionView moveItemAtIndexPath: toIndexPath:] чтобы выполнить анимацию для изменения или есть лучший метод ?



Я не получил много в подклассы collectionViews так что любая помощь будет большой...



спасибо,
Законопроект.

618   8  

8 ответов:

reloadData не анимируется и не делает это надежно, когда помещается в блок анимации UIView. Он хочет быть в блоке uicollecitonview performBatchUpdates, поэтому попробуйте что-то более похожее:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadData];
} completion:^(BOOL finished) {}];

упаковка -reloadData на -performBatchUpdates: не кажется, чтобы вызвать односекционный вид коллекции для анимации.

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadData];
} completion:nil];
этот код работает:
[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];

это то, что я сделал, чтобы оживить перезагрузку всех разделов:

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];

Swift 3

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)

для пользователей Swift, если ваш collectionview имеет только один раздел:

self.collectionView.performBatchUpdates({
                    let indexSet = IndexSet(integersIn: 0...0)
                    self.collectionView.reloadSections(indexSet)
                }, completion: nil)

Как видно на https://stackoverflow.com/a/42001389/4455570

текст справки говорит:

вызовите этот метод, чтобы обновить все элементы в представлении коллекции. Это приводит к тому, что представление коллекции отбрасывает все видимые в данный момент элементы и обновить их. Для повышения эффективности отображается только представление коллекции те ячейки и дополнительные виды, которые видны. Если данные коллекции сжимаются в результате перезагрузки, представление коллекции регулирует свои смещения прокрутки соответственно. Вы не должны называть это метод в середина анимационных блоков, где находятся элементы вставлено или удалено. Вставки и удаления автоматически вызывают данные таблицы должны быть соответствующим образом обновлены.

Я думаю, что ключевая часть - "заставляет представление коллекции отбрасывать любые видимые в настоящее время элементы". Как он собирается оживить движение предметов, которые он отбросил?

перезагрузка всего представления коллекции внутри performBatchUpdates:completion: блок делает глючную анимацию для меня на iOS 9 simulator. Если у вас есть конкретный UICollectionViewCell вы хотите удалить, или если у вас есть это путь к индексу, вы можете позвонить deleteItemsAtIndexPaths: в этом блоке. С помощью deleteItemsAtIndexPaths:, это делает гладкую и приятную анимацию.

UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;

[self.collectionView performBatchUpdates:^{
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
    // or...
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];

Если вы хотите больше контроля и настраиваемых функций проверки этой, он содержит очень подробное объяснение различных способов анимации UICollectionViewCell.

для пользователей swift это удобно -

collectionView.performBatchUpdates({ 

            self.collectionView.reloadSections(NSIndexSet(index: index))

            }, completion: nil)

Comments

    Ничего не найдено.