質問

現在、UICollectionViewを使用してUITableView並べ替え動作を実装しようとしています。

uicativeview tv uicollectionview cv を呼んでみましょう(以下の説明を明確にするため)

基本的にテレビのドラッグ&ドロップを再現しようとしていますが、編集モードを使用していないため、長押しジェスチャがトリガーされるとすぐにセルを移動する準備ができています。それは都道府県で働いています、私はCVの移動方法を使っています、すべてが大丈夫です。

ユーザーがセルをドラッグしているときにスクロールを処理するようにCVのContentOffsetプロパティを更新します。ユーザーが上部と下部にある特定の四角に移動すると、ContentOffsetとCVスクロールを更新します。問題は、ユーザーが指の動きを止めるとき、ジェスチャーはスクロールを停止させ、ユーザーが自分の指を移動するとすぐに再び開始する更新を送信しません。

この動作は間違いなく自然ではないが、私はそれがテレビでの場合としてCVを解放するまでスクロールするように連続することを好むでしょう。 TVドラッグ&ドロップの経験は素晴らしいです、そして私は本当に同じ気持ちを再現したいです。誰もが並べ替え中にテレビのスクロールを管理する方法を知っていますか?

  • ジェスチャーの位置が正しい場所にある限り、スクロール動作を繰り返しトリガーするためにタイマーを使って、スクロールはひどく、あまり生産的ではありません(非常に遅くてびっくり)。
  • 私はまたGCDを使って別のスレッドでジェスチャ位置を聞いてみましたが、結果はさらに最悪です。

私はそれについて考えを使い果たしたので、誰かが私が彼と結婚するだろう!

これは長押し方法の実装です:

- (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];
}
.

他のヒント

ここは代替案:

DragGableCollectionViewと

iOS 9以降、UICollectionViewは並べ替えをサポートしています。

UICollectionViewControllersの場合は、collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)

を上書きするだけです。

UICollectionViewsの場合、上記のUICollectionViewDataSourceメソッドを実装することに加えて、自分でジェスチャーを処理する必要があります。

これはソースからのコードです:

private var longPressGesture: UILongPressGestureRecognizer!

override func viewDidLoad() {
    super.viewDidLoad()

    longPressGesture = UILongPressGestureRecognizer(target: self, action: "handleLongGesture:")
    self.collectionView.addGestureRecognizer(longPressGesture)
}

func handleLongGesture(gesture: UILongPressGestureRecognizer) {

    switch(gesture.state) {

    case UIGestureRecognizerState.Began:
        guard let selectedIndexPath = self.collectionView.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else {
            break
        }
        collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
    case UIGestureRecognizerState.Changed:
        collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
    case UIGestureRecognizerState.Ended:
        collectionView.endInteractiveMovement()
    default:
        collectionView.cancelInteractiveMovement()
    }
}
.

ソース: HTTPS://developer.apple.com/library/ios/documentation/uikit/referentation/uicollectionView_class/#//apple_ref/doc/uid/tp40012177-ch1-sw67

> http://nshint.io/blog./ 2015/07/16 / UICollectionViews-easy-readering /

あなたがあなた自身を転がしてみると、あなたが見ることができる迅速なチュートリアルを書いたばかりです。この

ここは別のアプローチです:

鍵の違いは、この解決策が「ゴースト」または「ダミー」セルを必要としないため、ドラッグアンドドロップ機能を提供します。それは単にセル自体を使います。アニメーションはuibiteviewと並んでいます。移動中にコレクションビューレイアウトのプライベートデータソースを調整することで機能します。手放すと、自分のデータソースに変更をコミットできるようにコントローラに伝えます。

ほとんどのユースケースでは働くのは少し簡単だと思います。それでも進行中の仕事ですが、これを達成するもう1つの方法です。ほとんどの場合、これは彼ら自身のカスタムUICollectionViewLayoutsに組み込むことが非常に簡単です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top