防止触摸从UIControl传递到ParentView

时间:2018-09-27 15:33:25

标签: ios swift cocoa-touch uikit

我已经为Uber创建了一个自定义控件,例如OTP TextField。我想消耗控件中的触摸,而不是让它通过UIResponder链传播。因此,我已覆盖apple documentation.

中描述的方法
extension BVAPasswordTextField {
override func touchesBegan(_ touches: Set<UITouch>,  with event: UIEvent?) {
   becomeFirstResponder()
  }

  override func touchesMoved(Set<UITouch>, with: UIEvent?) {

}

override func touchesEnded(Set<UITouch>, with: UIEvent?) {

}

override func touchesCancelled(Set<UITouch>, with: UIEvent?) {

 }

override func touchesEstimatedPropertiesUpdated(Set<UITouch>) {

  }
}

现在,在某些视图控制器中,当用户点击自定义控件之外的任何位置时,我想关闭键盘。

override func viewDidLoad() {
    super.viewDidLoad()
    let tapGestureRecogniser = UITapGestureRecognizer(target: self, action: #selector(ViewController.backgroundTapped))
    tapGestureRecogniser.numberOfTapsRequired = 1
    view.addGestureRecognizer(tapGestureRecogniser)
    // Do any additional setup after loading the view, typically from a nib.
}

@objc func backgroundTapped() {
    self.view.endEditing(true)
}

但是每当我点击文本字段时,也会调用 backgroundTapped

注意:- 这是一个控件,您可以在其中基于枚举值创建不同的UI组件以进行输入。因此,可以在整个团队中共享此控件...我将不是唯一使用它的人。...所以我希望它的行为与触摸场景中的UITextfield完全一样

1 个答案:

答案 0 :(得分:0)

您可以使用UITapGestureRecognizerDelegate处理轻击手势。它使您可以决定是否应该开始手势。对于您来说,应该根据触摸的位置来完成。

extension ViewController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let location = gestureRecognizer.location(in: self.view)
        // return true is location of touch is outside our textField
        return !textField.frame.contains(location)
    }
}

只需确保为delegate上的手势设置了viewDidLoad

tapGestureRecogniser.delegate = self

更新

如果我的设置正确,则您将有一个视图和一些用于输入的子视图。并且您想触摸resignFirstRespondersuper-view。在这种情况下,您可以像这样使用gestureRecognizerShouldBegin

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    let location = gestureRecognizer.location(in: self.view)
    for subview in self.view.subviews {
        if subview.frame.contains(location) {
            return false
        }
    }
    return true
}

我认为,如果您想以特定的方式处理某些view交互,则需要使用该特定的view来进行。现在,您正在做的事情就像是尝试使用另一个视图更改一个view上的行为。