同一 UIView 中的两个 UIPanGestureRecognizer 同时调用

问题描述 投票:0回答:1

我希望两个

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).x < self.view.bounds.midY {
                return true
            } else {
                return false
            }
        }

        else if gestureRecognizer == self.panGesture2 {
            if gestureRecognizer.location(in: self.view).x > self.view.bounds.midY {
                return true
            } else {
                return false
            }
        }
}

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

        return true
}

当前问题

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

简单的出路

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

这可能吗?

在同一视图中使用两个平移手势是否可以实现这一点?

ios swift uiview uipangesturerecognizer
1个回答
0
投票

我确实希望您能得到使用 2 个手势识别器的答案。我自己也玩过,但放弃了。

在您看来启用

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) }
    }

}

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

© www.soinside.com 2019 - 2024. All rights reserved.