swift 同时调用同一UIView中的两个UIPanGestureRecognizers

1cklez4t  于 2023-09-30  发布在  Swift
关注(0)|答案(1)|浏览(118)

我想让两个UIPanGestureRecognizers在一个UIView中同时工作。在中心上方滑动会调用panGesture1,在中心下方滑动会调用panGesture2。同时使用这两种方法是可能的。

let panGesture1 = UIPanGestureRecognizer()
let panGesture2 = UIPanGestureRecognizer()

self.panGesture1.addTarget(self, action: #selector(self.panGesture1Detected(_:)))
self.panGesture1.delegate = self
self.panGesture1.minimumNumberOfTouches = 1
self.panGesture1.maximumNumberOfTouches = 1
self.panGesture1.cancelsTouchesInView = false
self.panGesture1.delaysTouchesBegan = false
self.panGesture1.delaysTouchesEnded = true
self.panGesture1.requiresExclusiveTouchType = false
self.view.addGestureRecognizer(self.panGesture1)

self.panGesture2.addTarget(self, action: #selector(self.panGesture2Detected(_:)))
self.panGesture2.delegate = self
self.panGesture2.minimumNumberOfTouches = 1
self.panGesture2.maximumNumberOfTouches = 1
self.panGesture2.cancelsTouchesInView = false
self.panGesture2.delaysTouchesBegan = false
self.panGesture2.delaysTouchesEnded = true
self.panGesture2.requiresExclusiveTouchType = false
self.view.addGestureRecognizer(self.panGesture2)


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

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if gestureRecognizer == self.panGesture1 {
            if gestureRecognizer.location(in: self.view).y < self.view.bounds.midY {
                //Pangesture 1 is above the first half of view. So good.
                return true
            } else {
                return false
            }
        }

        else if gestureRecognizer == self.panGesture2 {
            if gestureRecognizer.location(in: self.view).y > self.view.bounds.midY {
                //Pangesture 2 is below the first half of view. So good.
                return true
            } else {
                return false
            }
        }
}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {

        return true
}

本期

当第一次触摸平移时,它识别适当的平移手势。当第二触摸向下时,它假定这是针对当前活动的平移手势。因此基本上,两个平移手势的同时激活是不可能的。

Easy Way Out

在屏幕的一半上放一个虚拟的UIView,并在那里激活一个平移手势?

这可能吗?

在同一视图中使用两个平移手势是否可能?

dddzy1tm

dddzy1tm1#

我希望你能得到一个使用两个手势识别器的答案。我自己也试过,但还是放弃了。
在你的视图上启用isMultipleTouchEnabled可能还有一些可能,但我没有设法使它工作。
无论如何,平移手势是最容易自己实现的。他们完全没有微调。您只需要跟踪拖动。下面是一个非常简单的使用触摸事件的实现:

class CustomDragRecogniser {

    private var currentTouch: UITouch?

    // Control:
    var mayBegin: (_ touch: UITouch) -> Bool = { _ in true }
    var onBegin: (_ touch: UITouch) -> Void = { _ in }
    var onDrag: (_ touch: UITouch) -> Void = { _ in }
    var onEnded: (_ touch: UITouch) -> Void = { _ in }

    // Input:
    func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard currentTouch == nil else { return } // Already in progress
        if let matching = touches.first(where: { mayBegin($0) }) {
            currentTouch = matching
            onBegin(matching)
        }
    }

    func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let matching = touches.first(where: { $0 === currentTouch }) {
            onDrag(matching)
        }
    }

    func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let matching = touches.first(where: { $0 === currentTouch }) {
            currentTouch = nil
            onEnded(matching)
        }
    }

    func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let matching = touches.first(where: { $0 === currentTouch }) {
            currentTouch = nil
            onEnded(matching)
        }
    }

}

class SimultaneousGesturesViewController: UIViewController {

    private var recognisers: [CustomDragRecogniser] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        view.isMultipleTouchEnabled = true

        let topRecogniser = CustomDragRecogniser()
        topRecogniser.mayBegin = { [weak self] touch in
            guard let view = self?.view else { return false }
            return touch.location(in: view).y < view.bounds.height*0.5
        }
        topRecogniser.onDrag = { [weak self] touch in
            guard let view = self?.view else { return }
            print("G1 moved to \(touch.location(in: view))")
        }

        let bottomRecogniser = CustomDragRecogniser()
        bottomRecogniser.mayBegin = { [weak self] touch in
            guard let view = self?.view else { return false }
            return touch.location(in: view).y >= view.bounds.height*0.5
        }
        bottomRecogniser.onDrag = { [weak self] touch in
            guard let view = self?.view else { return }
            print("G2 moved to \(touch.location(in: view))")
        }

        recognisers = [topRecogniser, bottomRecogniser]
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        recognisers.forEach { $0.touchesBegan(touches, with: event) }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        recognisers.forEach { $0.touchesMoved(touches, with: event) }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        recognisers.forEach { $0.touchesEnded(touches, with: event) }
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        recognisers.forEach { $0.touchesCancelled(touches, with: event) }
    }

}

您应该能够将其打包到视图或其他工具中,以屏蔽大部分代码以实现可重用性。

相关问题