В настоящее время я пытаюсь реализовать поведение переупорядочения UITableView с помощью UICollectionView.
Позвоните в UItableView TV и CV UICollectionView (чтобы пояснить следующее объяснение)
Я в основном пытаюсь воспроизвести drag & drop телевизора, но я не использую режим редактирования, ячейка готова к перемещению, как только будет активирован длительный жест нажатия. Он работает префектно, я использую метод перемещения CV, все в порядке.
Я обновляю свойство contentOffset CV для обработки прокрутки, когда пользователь перетаскивает ячейку. Когда пользователь переходит к конкретному прямоугольнику сверху и снизу, я обновляю contentOffset и CV scroll. Проблема в том, что пользователь перестает перемещать его пальцем, этот жест не отправляет обновления, которое заставляет прокрутку останавливаться и запускаться снова, как только пользователь перемещает палец.
Такое поведение, безусловно, не является естественным, я бы предпочел продолжить прокрутку, пока пользователь не выпустит CV, как это имеет место в телевизоре. Опыт перетаскивания телевизора потрясающий, и я действительно хочу воспроизвести одно и то же чувство. Кто-нибудь знает, как они управляют прокруткой в телевизоре во время переупорядочения?
- Я попытался использовать таймер, чтобы вызвать действие прокрутки несколько раз, пока положение жестов находится в нужном месте, свиток был ужасным и не очень производительным (очень медленным и неустойчивым).
- Я также попытался использовать GCD для прослушивания позиции жестов в другом потоке, но результат даже хуже.
У меня кончилось представление об этом, поэтому, если у кого-то есть ответ, я выйду за него замуж!
Вот реализация метода longPress:
- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
{
ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
CGPoint gesturePosition = [sender locationInView:self.collectionView];
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:gesturePosition];
if (sender.state == UIGestureRecognizerStateBegan)
{
layout.selectedItem = selectedIndexPath;
layout.gesturePoint = gesturePosition; // Setting gesturePoint invalidate layout
}
else if (sender.state == UIGestureRecognizerStateChanged)
{
layout.gesturePoint = gesturePosition; // Setting gesturePoint invalidate layout
[self swapCellAtPoint:gesturePosition];
[self manageScrollWithReferencePoint:gesturePosition];
}
else
{
[self.collectionView performBatchUpdates:^
{
layout.selectedItem = nil;
layout.gesturePoint = CGPointZero; // Setting gesturePoint invalidate layout
} completion:^(BOOL completion){[self.collectionView reloadData];}];
}
}
Чтобы сделать прокрутку CV, я использую этот метод:
- (void)manageScrollWithReferencePoint:(CGPoint)gesturePoint
{
ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
CGFloat topScrollLimit = self.collectionView.contentOffset.y+layout.itemSize.height/2+SCROLL_BORDER;
CGFloat bottomScrollLimit = self.collectionView.contentOffset.y+self.collectionView.frame.size.height-layout.itemSize.height/2-SCROLL_BORDER;
CGPoint contentOffset = self.collectionView.contentOffset;
if (gesturePoint.y < topScrollLimit && gesturePoint.y - layout.itemSize.height/2 - SCROLL_BORDER > 0)
contentOffset.y -= SCROLL_STEP;
else if (gesturePoint.y > bottomScrollLimit &&
gesturePoint.y + layout.itemSize.height/2 + SCROLL_BORDER < self.collectionView.contentSize.height)
contentOffset.y += SCROLL_STEP;
[self.collectionView setContentOffset:contentOffset];
}