我希望两个
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 放在屏幕的一半上,并在那里激活其中一个平移手势?
在同一视图中使用两个平移手势是否可以实现这一点?
我确实希望您能得到使用 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) }
}
}
您应该能够将其打包到视图或其他工具中,以屏蔽大部分代码以实现可重用性。