触摸同级时关闭键盘

时间:2015-12-23 02:29:22

标签: ios iphone swift uiview

尽管所有"解雇键盘"问题,似乎没有人提到这个具体情况。

我正在使用具有以下(简化)层次结构的ViewController:

  • 的UIView
    • 的UIScrollView
      • UIStackView
        • PLCustomViewOne
          • 的UIButton
          • 的UITextField
        • PLCustomViewTwo
          • 的UIButton
          • 的UITextField

ViewController从XIB加载,两个PLCustomView也是如此。当用户选择UIStackViews包含的任何内容时,我似乎无法将视图转到endEditing(取消键盘)。

向视图添加手势识别器肯定会起作用;但是,这要求层次结构中的每个视图都会添加添加到其中的手势识别器,这看起来并不具有可扩展性。实际版本实际上有很多子视图。

我尝试将touchesBegan中的解雇添加到每个自定义视图的UIView子类中,但这只会在用户触摸包含firstResponder的视图时解除键盘。例如,如果PLCustomViewOne中的textField处于活动状态,则触摸该视图中的任何其他位置都会取消键盘,但触摸它外部,例如PLCustomViewTwo,则不会。

2 个答案:

答案 0 :(得分:1)

在视图控制器类中,为两个自定义视图创建插座(通过从故事板中按住Ctrl键拖动)

@IBOutlet weak var customViewOne: PLCustomViewOne!
@IBOutlet weak var customViewTwo: PLCustomViewTwo!

通过这些,您应该能够访问您的UITextField实例,例如

customViewOne.textField
customViewTwo.textField

(最好是在自定义类中将此属性设置为非私有属性)。另外(在您查看控制器类中)创建一个私有UITextField属性来保存(可能)当前(/最近使用的)文本字段。

private var currentTextField: UITextField?

重载viewDidLoad子类的UIViewController方法,以初始化两个" public"的代理。文本字段实例

override func viewDidLoad() {
    super.viewDidLoad()

    // Handle the user input in the text fields through delegate callbacks (and set tags)
    customViewOne.textField.delegate = self
    customViewOne.textField.delegate = self
}

此外,使用textFieldShouldReturn(...)的两个textFieldDidBeginEditing(...)UITextFieldDelegate方法将(活动)文本字段状态作为第一响应者重新签名并更新{{1}分别是引用。

currentTextField

最后(同样在视图控制器类中),将任何可能的当前文本字段作为第一响应者重新签名,以防在编辑中间按下任意两个按钮时/或者当触摸在<强大的>任何的UIView

// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
    // User finished typing (hit return): hide the keyboard.
    textField.resignFirstResponder()
    return true
}

func textFieldDidBeginEditing(textField: UITextField) {
    currentTextField = textField
}

这里的关键是你跟踪哪个文本字段是第一响应者(通过视图控制器中的... user does action/tap/gesture elsewhere { if let currentTextField = currentTextField { currentTextField.resignFirstResponder() } } 属性),并且只调用此文本字段。

答案 1 :(得分:0)

我可以通过在自定义视图中添加以下内容来实现所需的结果:

private func addTapToResignFirstResponder () {
    let action = UITapGestureRecognizer(target: self, action: Selector("dismissFirstResponder"))
    self.view.addGestureRecognizer(action)
}

func dismissFirstResponder () {
    UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)
}

addTapToResignFirstResponder()的初始化中调用UIView

无论在何处,无需参考,全球都会对第一响应者进行解雇。

dismissFirstResponder()也可以在子类中重写,以获得额外的灵活性。