Когда последовательность касаний происходит в области перекрывающихся видов, по сути, между жестами происходит захват этой последовательности касаний.
Может быть, попробовать это?
Мы ставим прозрачный вид на сверху, и назначьте ему собственный распознаватель жестов. Идея состоит в том, чтобы заставить этот жест действовать как своего рода посредник, который определяет, какой вид выбора получает последовательность касаний; вместо того, чтобы они боролись между собой, а верхний всегда побеждает.
У каждого представления выбора есть свой собственный жест, и мы скажем обоим требовать, чтобы наш пользовательский жест потерпел неудачу. Это означает, что наш собственный жест должен сначала потерпеть неудачу, прежде чем эти жесты смогут получить последовательность касания.
В коде нашего настраиваемого жеста мы всегда устанавливаем его состояние как сбойное, что позволяет последовательности касания быть перешел на другие жесты. Но прежде чем мы потерпим неудачу, мы определим, какое представление выбора должно получить эту последовательность касаний, установив userInteractionEnabled в обоих представлениях выбора соответственно. Это, конечно, в надежде, что если мы отключим userInteraction в представлении, то это представление не получит переданную последовательность касания. Может быть, в этом случае мы придем к чему-то еще.
Вот код для нашего пользовательского жеста, с которого можно начать:
import UIKit.UIGestureRecognizerSubclass
class BrokerGesture: UIPanGestureRecognizer {
private var startPoint: CGPoint!
private var views: [UIView]
override init(target: Any?, action: Selector?, views: [UIView]) {
self.views = views
super.init(target: target, action: action)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
self.startPoint = touches.first!.location(in: self.view!.superview)
super.touchesBegan(touches, with: event)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
if self.state == .possible {
let loc = touches.first!.location(in: self.view!.superview)
let deltaX = abs(loc.x - self.startPoint.x)
let deltaY = abs(loc.y - self.startPoint.y)
// Your code here:
// - Use deltaX and deltaY
// - Set userInteraction on both views accordingly
self.state = .failed
} else {
super.touchesMoved(touches, with: event)
}
// Don't call super here! It will just set the state to .began! and we don't want to do that.
}
}