События жестов касания в области перекрытия - PullRequest
1 голос
/ 27 сентября 2019

У меня есть вид с черной рамкой, и у него два разных вида.И эти взгляды частично совпадают.И у каждого из них есть свой UITapGestureRecognizer.Когда я нажимаю на отдельную область каждого элемента, действие этого элемента запускается.Но когда я нажимаю на общую область, срабатывает только действие второго вида.Я хочу, чтобы оба действия были запущены.Как мне этого добиться?Вот мой код:

class ViewController: UIViewController {

  @IBOutlet weak var view1: UIView!
  @IBOutlet weak var view2: UIView!
  @IBOutlet weak var outerView: UIView!

  override func viewDidLoad() {
      super.viewDidLoad()
      outerView.layer.borderWidth = 2.0
      outerView.layer.borderColor = UIColor.black.cgColor
      view1.layer.borderWidth = 2.0
      view1.layer.borderColor = UIColor.red.cgColor
      view2.layer.borderWidth = 2.0
      view2.layer.borderColor = UIColor.blue.cgColor
      self.initialize()
  }

  private func initialize(){
      let tapGesture1 = UITapGestureRecognizer(target: self, action: #selector(detectTap1(_:)))
      let tapGesture2 = UITapGestureRecognizer(target: self, action: #selector(detectTap2(_:)))
      self.view1.addGestureRecognizer(tapGesture1)
      self.view2.addGestureRecognizer(tapGesture2)
  }

  @objc func detectTap1(_ gesture : UITapGestureRecognizer) {
      print("detectTap1")
  }

  @objc func detectTap2(_ gesture : UITapGestureRecognizer) {
      print("detectTap2")
  }
}

example

Пожалуйста, поделитесь вашими предложениями.

Ответы [ 3 ]

2 голосов
/ 27 сентября 2019

Для этой проблемы я нашел это решение, возможно, это не лучшее решение, но оно работает, я все равно буду искать дальнейшие улучшения

У меня есть подклассы UIGestureRecognizer класс

Обновлено

import UIKit
import UIKit.UIGestureRecognizerSubclass

class CustomGestureRecognizer: UIGestureRecognizer {

    var anotherGestureRecognizer : CustomGestureRecognizer?
    private var touchBeganSended : Bool = false
    private var touchLocation : CGPoint?

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        if let validTouch = touches.first?.location(in: self.view) {
            if (self.view!.point(inside: validTouch, with: event)) {
                if(!touchBeganSended) {
                    touchBeganSended = true
                    touchLocation = validTouch
                    anotherGestureRecognizer?.touchesBegan(touches, with: event)
                    state = .recognized
                }
            }
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesEnded(touches, with: event)
        if let validTouch = touches.first?.location(in: self.view) {
            if (self.view!.point(inside: validTouch, with: event)) {
                if(touchBeganSended) {
                    touchBeganSended = false
                    anotherGestureRecognizer?.touchesEnded(touches, with: event)
                    state = .recognized
                }
            }
        }
    }

    override func location(in view: UIView?) -> CGPoint {
        if let desiredView = view {
            if(desiredView == self.view) {
                return touchLocation ?? CGPoint(x: 0, y: 0)
            } else {
                return super.location(in: view)
            }
        } else {
            return super.location(in: view)
        }
    }
}

Обновлен

, затем вам нужно изменить метод initialize() на этот, с последним обновлением , которое вам не нужночтобы принять во внимание, какое представление находится сверху в иерархии представлений

private func initialize(){
    let tapGesture1 = CustomGestureRecognizer(target: self, action: #selector(detectTap1(_:)))
    let tapGesture2 = CustomGestureRecognizer(target: self, action: #selector(detectTap2(_:)))
    tapGesture1.cancelsTouchesInView = true
    tapGesture1.delegate = self
    tapGesture2.cancelsTouchesInView = true
    tapGesture2.delegate = self
    self.view1.addGestureRecognizer(tapGesture1)
    tapGesture1.anotherGestureRecognizer = tapGesture2
    tapGesture2.anotherGestureRecognizer = tapGesture1
    self.view2.addGestureRecognizer(tapGesture2)
}

, это работает, как вы можете видеть здесь

enter image description here

0 голосов
/ 27 сентября 2019

Попробуйте реализовать этот UIGestureRecognizerDelegate метод:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

... 
...

private func initialize() {
...
  gesture1.delegate = self
  gesture2.delegate = self
...
}

func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
 shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
    // its up to you 
    //guard otherGestureRecognizer == yourAnotherGesture else { return false }
    return true
}
0 голосов
/ 27 сентября 2019

Попробуйте следующее:

private func initialize(){

        let tapGesture1 = UITapGestureRecognizer(target: self, action: #selector(detectTap1(_:)))
        let tapGesture2 = UITapGestureRecognizer(target: self, action: #selector(detectTap2(_:)))
        tapGesture1.cancelsTouchesInView = false
        tapGesture2.cancelsTouchesInView = false
        self.view1.addGestureRecognizer(tapGesture1)
        self.view2.addGestureRecognizer(tapGesture2)
 }

Когда вы устанавливаете

gest.cancelsTouchesInView = false

, он распространяет жест на представления под ним.

...