UIButton不受UITapGestureRecoginzer的影响。

时间:2018-03-13 14:59:18

标签: ios swift uitapgesturerecognizer

我有一个UIImageView(userInteractionEnabled)UIButtonUITextField都是superview的子视图,其中添加了UITapGestureRecognizer个。因此我的superviewUIImageView 回复来点按手势,但UIButtonUITextField 忽略。这是UITapGestureRecognizer的政策添加到superview这是我的错吗?有谁知道这种情况?

这是我的代码,包含视图子视图和gestureRecognizer

 @objc   func tapBlurButton(_ sender: UITapGestureRecognizer) {
    print("Please Help!")
    endEditing(true)

}


override init(frame: CGRect) {
    super.init(frame: frame)
   //     backgroundColor = UIColor.green

    addSubview(logoImageView)
   // addSubview(skipButton)
   addSubview(emailTextField)
   addSubview(passwordTextField)
    addSubview(loginButton)
     observeKeyboardNotifications()


 //   logoImageView.translatesAutoresizingMaskIntoConstraints = false
    logoImageView.anchorWithConstantsToTop(centerYAnchor, left: nil  , bottom: nil, right: nil, topConstant: -230, leftConstant: 0, bottomConstant: 0, rightConstant: 0)
    logoImageView.widthAnchor.constraint(equalToConstant: 160).isActive = true
    logoImageView.heightAnchor.constraint(equalToConstant: 160).isActive = true
    logoImageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true

    emailTextField.anchorWithConstantsToTop(logoImageView.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 8, leftConstant: 32, bottomConstant: 0, rightConstant: 32)
    emailTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
    passwordTextField.anchorWithConstantsToTop(emailTextField.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 8, leftConstant: 32, bottomConstant: 0, rightConstant: 32)
    passwordTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
    loginButton.anchorWithConstantsToTop(passwordTextField.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 16, leftConstant: 32, bottomConstant: 0, rightConstant: 32)
    loginButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
    isUserInteractionEnabled = true
    addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(LoginCell.tapBlurButton(_:))))
    isUserInteractionEnabled = true

 }

我看到其他答案,他们只是告诉我们如何解决它,但他们并没有真正理由为什么会发生这种情况,而且没有人会提到完全讲述这个问题的文档。所以我的问题不是问如何避免它或如何解决它,我想知道它为什么会发生,我是正确的,当我怀疑UIkit这样做,所以这不是我的错,或者我错了,错过了什么?< / p>

1 个答案:

答案 0 :(得分:2)

Apple提供了一篇非常简单实用的文章。要了解您的需求,您应该查看 Responder Chain 概念。

Understanding Event Handling, Responders, and the Responder Chain

基本上,如果您想了解点击的UIImageView 回复的原因,UIButtonUITextField 不要这样做,有一个简单的解释。 UIButtonUITextFieldUIControl个子类,但UIImageView不是,它只是UIResponder的子类。因此,每个UIControl使用目标 - 操作机制,但UIResponder不会这样做。

UIControl docs

enter image description here

文档说:

  

控件直接与其关联的目标对象进行通信   使用动作消息。当用户与控件交互时,   control调用其目标对象的action方法 - 换句话说,   它向其目标对象发送一条动作消息。动作消息是   不是事件,但他们仍然可以利用响应者链。   当控件的目标对象为nil时,UIKit从   目标对象并遍历响应者链,直到找到对象为止   实现适当的行动方法。

因此,当您单击UIControl对象时,它意味着默认,它不会将该事件传播到superview来处理它。控件覆盖默认的UIResponder行为。但是当你点击UIResponder时,它会将事件发送到超级视图来处理它,触摸就会消失。因此,UIKit执行此操作,并且通常UITapGestureRecognizer默认情况下不会通过UIControl,因为控件具有一组预设事件并使用另一种处理它们的机制。但是,当您停用UIControl与用户点击互动的功能时,您的超级视图点击手势识别器会响应。

在您的情况下,如果您设置了该选项,即使您按下按钮也会调用func tapBlurButton(_ sender: UITapGestureRecognizer),因为该按钮不会尝试处理该事件,并且触摸将直接进入上海华。

loginButton.isUserInteractionEnabled = false