Я испытываю кражу sh, пытающуюся анимировать множественные изменения в представлении коллекции, когда изменения связаны с перемещением раздела.
Самый простой случай, который я мог создать для воспроизведения проблемы, - это представление коллекции с две секции (I
и II
) и три предмета (A
, B
и C
). Попытка оживить изменения от [[I: A, B],[II: C]]
до [[II: C],[I: B]]
регистрирует сообщение [General] request for index path for global index 2 when there are only 2 items in the collection view
и выдает сбой с *** Assertion failure in -[NSCollectionViewData indexPathForItemAtGlobalIndex:]
.
Код для внесения изменений:
// The line marked (1) causes the crash
collectionView.animator().performBatchUpdates({
collectionView.deleteItems(at: [IndexPath(item: 0, section: 0)])
collectionView.moveSection(0, toSection: 1) // (1)
collectionView.moveItem(at: IndexPath(item: 0, section: 1), to: IndexPath(item: 0, section: 0))
})
Я осторожно передавайте исходные индексы / пути в delete
и move
из местоположений, а целевые индексы / пути в move
в местоположения.
И мой (жестко заданный для целей тестирования) источник данных выглядит следующим образом:
// Configuration 1 (2 sections, 3 items): [[I: A, B],[II: C]]
// Configuration 2 (2 sections, 2 items): [[II: C],[I: B]]
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
if configuration == 1 {
switch section {
case 0: return 2
case 1: return 1
default: preconditionFailure()
}
}
else {
switch section {
case 0: return 1
case 1: return 1
default: preconditionFailure()
}
}
}
На основании обратной трассировки создается впечатление, что представление сбора собирает информацию макета для анимации:
0 CoreFoundation 0x00007fff33ae28ab __exceptionPreprocess + 250
1 libobjc.A.dylib 0x00007fff69bba805 objc_exception_throw + 48
2 CoreFoundation 0x00007fff33b0bd10 +[NSException raise:format:arguments:] + 88
3 Foundation 0x00007fff36204221 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
4 UIFoundation 0x00007fff646c017b -[NSCollectionViewData indexPathForItemAtGlobalIndex:] + 271
5 UIFoundation 0x00007fff646c07b6 -[NSCollectionViewData layoutAttributesForGlobalItemIndex:] + 23
6 UIFoundation 0x00007fff6470ac58 -[_NSCollectionViewCore _viewAnimationsForCurrentUpdate] + 5949
7 UIFoundation 0x00007fff6470e608 __76-[_NSCollectionViewCore _updateWithItems:tentativelyForReordering:animator:]_block_invoke.1051 + 161
8 UIFoundation 0x00007fff6465afc5 +[_NSUIAnimator performWithoutAnimation:] + 87
9 UIFoundation 0x00007fff6470db6d -[_NSCollectionViewCore _updateWithItems:tentativelyForReordering:animator:] + 736
10 UIFoundation 0x00007fff6470913b -[_NSCollectionViewCore _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:] + 16038
11 UIFoundation 0x00007fff6470f912 -[_NSCollectionViewCore _endUpdatesWithInvalidationContext:tentativelyForReordering:animator:] + 67
12 UIFoundation 0x00007fff6470fd82 -[_NSCollectionViewCore _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:] + 680
13 UIFoundation 0x00007fff6470fab7 -[_NSCollectionViewCore _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 90
14 UIFoundation 0x00007fff6470fa3a -[_NSCollectionViewCore _performBatchUpdates:completion:invalidationContext:] + 74
15 UIFoundation 0x00007fff6470f98f -[_NSCollectionViewCore performBatchUpdates:completion:] + 53
16 AppKit 0x00007fff31591778 -[NSCollectionView performBatchUpdates:completionHandler:] + 282
17 AppKit 0x00007fff31747929 ___withImplicitAnimationEnabledDo_block_invoke + 52
18 AppKit 0x00007fff30c4abe5 +[NSAnimationContext runAnimationGroup:] + 55
19 AppKit 0x00007fff317476b6 -[_NSViewAnimator_NSCollectionView performBatchUpdates:completionHandler:] + 125
Я использую стандартную схему потока.
Полный пример, показывающий проблему: https://github.com/sbooth/NSCollectionViewBatchUpdateCrash
Что необходимо изменить, чтобы правильно ли анимировать изменения как пакет?