如何指定相同类型的UIGestureRecognizer的优先级?

时间:2019-01-17 03:42:59

标签: ios swift uigesturerecognizer uitapgesturerecognizer

我有一个基本的UIView,另一个UIView嵌套在其中。想象一个盒子里面有一个小盒子。它甚至可能是内部的UIImageView。只是某种类型的视图。两个视图中的每个视图都必须具有UITapGestureRecognizer。当我在内部视图之外的外部视图中点击任意位置时,我将执行一项操作。当点击内部视图时,我想执行其他操作。

示例:我有一个外部容器视图和一个内部UIImageView。如果我在内部视图之外点击外部视图,那么我会转到下一个屏幕。如果我点击内部图像视图,那么它将在弹出窗口中以较大版本显示图像。

我很难确定优先级。我知道内部视图所在的UITapGestureRecognizers重叠,但是我想指定内部视图识别器始终优先于外部视图。

Apple在https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers/preferring_one_gesture_over_another的文档中指定了如何区分不同类型的手势识别器的方法,但是使用相同的两个手势识别器和相同的委托不会显示该区别。这是如何实现的?也许我没有正确理解文档。

我将手势识别器附加到代码中的视图上,并且在将手势识别器添加到不同视图中时尝试进行交换,在内部视图识别器之前添加外部视图识别器,然后相反。但是,它仍然每次都仅注册外视图点击手势识别器。

下面是一些代码。我在界面构建器中创建了带有特定视图的出口的视图。 campaignContentView是父视图,pictureImageViewlinkDetailsView是子视图。有时我只是显示一张图片,该图片应该做一件事。其他时候,我有一个带有关联缩略图的链接,然后点击其中任何一个都可以做另一件事。

@IBOutlet weak var campaignContentView: UIView!
@IBOutlet weak var pictureImageView: UIImageView!
@IBOutlet weak var linkDetailsView: UIView!

private func addNewGestureRecognizer(_ view: UIView) {
        let tapView = UITapGestureRecognizer(target: self, action: #selector(CampaignActionContentView.tappedView(_:)))
        campaignContentView.addGestureRecognizer(tapView)

        switch view {
        case linkDetailsView:
            let tapLinkDetails = UITapGestureRecognizer(target: self, action: #selector(CampaignActionContentView.tappedLink(_:)))
            let tapLinkPicture = UITapGestureRecognizer(target: self, action: #selector(CampaignActionContentView.tappedLink(_:)))
            view.addGestureRecognizer(tapLinkDetails)
            pictureImageView.addGestureRecognizer(tapLinkPicture)
        case pictureImageView:
            let tapPicture = UITapGestureRecognizer(target: self, action: #selector(CampaignActionContentView.tappedPicture(_:)))
            view.addGestureRecognizer(tapPicture)
        default:
            print("No new gesture necessary")
        }
    }

我也相应地致电bringSubviewToFront(pictureImageView)bringSubviewToFront(linkDetailsView)。事实证明,linkDetailsView的手势识别器实际上在正常工作,而不是pictureImageView

1 个答案:

答案 0 :(得分:1)

这不能回答如何指定优先级,但是我可以解决您的问题。我认为除非一个视图具有两个手势,否则您不需要使用手势优先级。在您的情况下,您有两个具有各自手势的视图。

我认为您的真正问题是您的内部视图不在外部视图之上。我建议看一下视图层次调试器。我在视图中创建了一个视图,并能够确定自己的轻击手势。

我在操场上用手势创建了一个简单的两个盒子...

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let innerView = UIView()
        innerView.backgroundColor = UIColor.red

        view.addSubview(innerView)
        innerView.translatesAutoresizingMaskIntoConstraints = false
        innerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        innerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        innerView.widthAnchor.constraint(equalToConstant: 100).isActive = true
        innerView.heightAnchor.constraint(equalToConstant: 100).isActive = true

        self.view = view

        let outTapGesture = UITapGestureRecognizer(target: self, action: #selector(outterViewTapped))
        let innerTapGesture = UITapGestureRecognizer(target: self, action: #selector(innerViewTapped))

        view.addGestureRecognizer(outTapGesture)
        innerView.addGestureRecognizer(innerTapGesture)
    }

     @objc func outterViewTapped() {
       print("Outter tapped!")
     }

     @objc func innerViewTapped() {
       print("Inner tapped!")
     }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()