【问题标题】:How do you specify priority of the same type of UIGestureRecognizer?同类型的UIGestureRecognizer如何指定优先级?
【发布时间】:2019-06-11 05:26:13
【问题描述】:

我有一个基本的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

【问题讨论】:

  • 您可以提供任何示例项目或代码吗?
  • 如果把内部视图放到前面呢?
  • 所以我这样做了,但它仍然不能完全正常工作。我添加了代码和细节。

标签: ios swift uigesturerecognizer uitapgesturerecognizer


【解决方案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()

【讨论】:

  • 感谢您的回复。我在一些代码中添加了 sn-ps 和上下文。我仍然无法让手势识别器为图像视图工作,尽管单独的手势识别器可以在常规 ui 视图中正常工作。
  • @casperson 为您的 imageView,您是否允许设置 .userInteractionEnabled = true?默认情况下,ImageViews 不能被用户交互。
  • 确实如此。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
相关资源
最近更新 更多