如果另一个同时平移没有结束,UICollectionView的panGestureRecognizer将不会重置

时间:2018-06-11 12:11:54

标签: ios swift uicollectionview uikit uigesturerecognizer

我正在努力应对让多个手势识别器很好地协同工作的棘手挑战。基本上我正在尝试实现类似于Apple的原生Drag& amp;在iOS 11中引入的丢弃行为。由于各种原因(主要是拖延时间的长时间延迟)本机API不适合我们的用例,所以我正在尝试实现自定义行为。

我有一个全屏UICollectionView,我希望用两根手指平移。这可以通过collectionView.panGestureRecognizer.minimumNumberOfTouches = 2

轻松完成

此collectionView的父级还附加了一个panGestureRecognizer,maximumNumberOfTouches = 1。这个识别器处理诸如拾取子视图和拖动它们以及移动(一个手指)触摸之类的东西。到现在为止还挺好。我可以选择一些东西,拖动它,然后(当第一次拖动仍在进行时)使用两个手指平移collectionView,而拖动的项目在父级的视图层次中保持可见。

现在出现了问题:一旦collectionView上的平移已经结束,只要我不放开第一个手指(与另一个平移手势相关的手指),collectionView就会保持无响应状态。除非我结束第一个手势,否则它将无法识别任何进一步的双指平底锅。

我对此进行了一系列调试,似乎在手势结束后,collectionView的panGestureRecognizer的内部状态未被重置为.possible。我已经尝试了很多东西来解决这个问题,即使是最讨厌和奇怪的想法,但我只是无法解决这个问题。对此的任何想法都将受到无限的赞赏。

我将问题分离到一个小的UIViewController子类中,可以将其抛入一个空项目中以重现该问题:

import UIKit

class ViewController: UIViewController, UIGestureRecognizerDelegate, UICollectionViewDataSource {

    var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.itemSize = view.bounds.size
        flowLayout.minimumLineSpacing = 0
        flowLayout.minimumInteritemSpacing = 0

        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: flowLayout)
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        collectionView.dataSource = self
        collectionView.isPagingEnabled = true
        collectionView.panGestureRecognizer.minimumNumberOfTouches = 2
        view.addSubview(collectionView)

        let panRec = UIPanGestureRecognizer(target: self, action: #selector(didOneFingerPan(_:)))
        panRec.delegate = self
        panRec.maximumNumberOfTouches = 1

        view.addGestureRecognizer(panRec)
    }

    @objc func didOneFingerPan(_ rec: UIPanGestureRecognizer) {
        print("didOneFingerPan: \(rec.state.rawValue)")
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.backgroundColor = indexPath.item % 2 == 0 ? .yellow : .red
        return cell
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

0 个答案:

没有答案