現在、UICollectionView を使用して UITableView の並べ替え動作を実装しようとしています。
UItableView TVとUICollectionView CVを呼び出しましょう(以下の説明を明確にするため)
基本的にテレビのドラッグ&ドロップを再現しようとしているのですが、編集モードは使っておらず、長押しジェスチャがトリガーされるとすぐにセルを移動できるようになっています。それは完全に機能します。CVの移動方法を使用しています。すべて問題ありません。
ユーザーがセルをドラッグしているときにスクロールを処理するために、CV の contentOffset プロパティを更新します。ユーザーが上下の特定の四角形に移動すると、contentOffset と CV スクロールを更新します。問題は、ユーザーが指の動きを止めると、ジェスチャーが更新を送信しないため、ユーザーが指を動かすとすぐにスクロールが停止して再開することです。
この動作は間違いなく自然ではありません。テレビの場合のように、ユーザーが 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];
}