Я попытался реализовать встроенное переупорядочение CollectionView, которое было представлено начиная с iOS10, в соответствии с этим руководством: http://nshint.io/blog/2015/07/16/uicollectionviews-now-have-easy-reordering/ и все работает нормально на iOS11, но вылетает на iOS10 при запуске перетаскивания любого элемента (ячейки) в UICollectionView
Вот мой код:
- (void)addCollectionViewGestureRecognizers
{
if (!self.panGesture)
{
// gesture to drag and reorder tiles
self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleCollectionViewPanGesture:)];
[self.collectionView addGestureRecognizer:self.panGesture];
}
}
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
CLog(@"Item moved from index path: %@ to index path: %@", sourceIndexPath, destinationIndexPath);
}
- (void)handleCollectionViewPanGesture:(UIPanGestureRecognizer *)gesture
{
switch(gesture.state)
{
case UIGestureRecognizerStateBegan:
{
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:[gesture locationInView:self.collectionView]];
if (selectedIndexPath)
{
[self.collectionView beginInteractiveMovementForItemAtIndexPath:selectedIndexPath];
}
break;
}
case UIGestureRecognizerStateChanged:
{
[self.collectionView updateInteractiveMovementTargetPosition:[gesture locationInView:gesture.view]];
break;
}
case UIGestureRecognizerStateEnded:
{
[self.collectionView endInteractiveMovement];
break;
}
default:
{
[self.collectionView cancelInteractiveMovement];
break;
}
}
}
и iOS 10 каждый раз вылетает в сети:
[self.collectionView updateInteractiveMovementTargetPosition:[gesture locationInView:guesture.view]];
Отчет о сбое:
0 CoreFoundation 0x0000000118f8bb0b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000118961141 objc_exception_throw + 48
2 CoreFoundation 0x0000000118ec0443 -[__NSArrayM insertObject:atIndex:] + 1603
3 UIKit 0x00000001166f3577 -[UICollectionView _getOriginalReorderingIndexPaths:targetIndexPaths:] + 501
4 UIKit 0x00000001166e2e50 -[UICollectionView _viewAnimationsForCurrentUpdate] + 7338
5 UIKit 0x00000001166e7bf3 __71-[UICollectionView _updateWithItems:tentativelyForReordering:animator:]_block_invoke.2012 + 197
6 UIKit 0x0000000115e4c08e +[UIView(Animation) performWithoutAnimation:] + 90
7 UIKit 0x00000001166e682d -[UICollectionView _updateWithItems:tentativelyForReordering:animator:] + 3856
8 UIKit 0x00000001166e0b33 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:] + 17030
9 UIKit 0x00000001166e91cd -[UICollectionView _endUpdatesWithInvalidationContext:tentativelyForReordering:animator:] + 71
10 UIKit 0x00000001166e9514 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:] + 437
11 UIKit 0x00000001166e933c -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 91
12 UIKit 0x00000001166f09a3 -[UICollectionView _updateReorderingTargetPosition:forced:] + 1467
13 UIKit 0x00000001166f122a -[UICollectionView updateInteractiveMovementTargetPosition:] + 29
14 myAPP 0x000000010dcb3b26 -[MenuCollectionViewController handleCollectionViewPanGesture:] + 710
15 UIKit 0x00000001162c8f59 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 57
16 UIKit 0x00000001162d0d57 _UIGestureRecognizerSendTargetActions + 109
17 UIKit 0x00000001162ce70b _UIGestureRecognizerSendActions + 225
Я что-то забыл установить?
Буду очень признателен, если у кого-то есть идеи по этому поводу ...
@staticVoidMan, извини, это у меня плохо. Когда я копировал и вставлял код, я по ошибке изменил guesture.view на self.view. Исходный код - [gesture locationInView: gesture.view], и он дает сбой только на iOS10.
@staticVoidMan, кажется, я нашел место, где найти проблему. У меня есть собственный макет, унаследованный от UICollectionViewFlowLayout и переопределяющий в нем функцию targetIndexPathForInteractivelyMovingItem. Если прокомментировать это переопределение, переупорядочивание работы без сбоев. просто элемент перемещается на неправильный indexPath
большой! вы также должны отметить свой ответ как принятый
Хорошо, кажется, я нашел причину этого сбоя и возможное решение. У меня есть собственный макет, унаследованный от UICollectionViewFlowLayout и переопределяющий в нем функцию targetIndexPathForInteractivelyMovingItem. Переместить предметы в правильное место. Я реализовал это так:
- (NSIndexPath*)targetIndexPathForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath withPosition:(CGPoint)position
{
NSIndexPath *targetIndexPath = [self.collectionView indexPathForItemAtPoint:position];
return targetIndexPath;
}
И это отлично работает на iOS 11, но для iOS 10 indexPathForItemAtPoint по какой-то причине возвращает nil (я не уверен, почему) Поэтому мне пришлось добавить этот трюк, чтобы предотвратить сбой при переупорядочивании
- (NSIndexPath*)targetIndexPathForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath withPosition:(CGPoint)position
{
NSIndexPath *targetIndexPath = [self.collectionView indexPathForItemAtPoint:position];
if (!targetIndexPath) // on iOS10 indexpath can be nil by some reason
{
targetIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
}
return targetIndexPath;
}
Я думаю, что это должен быть
[self.collectionView updateInteractiveMovementTargetPosition:[gesture locationInView:gesture.view]];
Обратите внимание, что это неself.view
, а фактическиgesture.view