简体   繁体   English

如何获取当前活动的UITextField / UITextView和resignFirstResponder?

[英]How to get the currently active UITextField/UITextView and resignFirstResponder?

Is it possible to get the currently active UITextField or UITextView in a UIView, so I can hide the keyboard with [text resignFirstResponder]; 是否可以在UIView中获取当前活动的UITextField或UITextView,所以我可以使用[text resignFirstResponder];隐藏键盘[text resignFirstResponder]; ?

As of iOS 2.0 and later, there is an easy way to dismiss the keyboard without having to track the currently active control, or iterating through all the available controls, or using a UITextFieldDelegate . 从iOS 2.0及更高版本开始,有一种简单的方法可以关闭键盘,而不必跟踪当前活动的控件,或遍历所有可用控件,或使用UITextFieldDelegate

[self.view endEditing:YES]

From the docs: 从文档:

endEditing: endEditing:

Causes the view (or one of its embedded text fields) to resign the first responder status. 使视图(或其嵌入式文本字段之一)退出第一响应者状态。

- ( BOOL )endEditing:( BOOL ) force -( BOOL )endEditing :( BOOL强制

Parameters 参量
force
Specify YES to force the first responder to resign, regardless of whether it wants to do so. 指定YES以强制第一响应者辞职,无论它是否愿意这样做。

Return Value 返回值
YES if the view resigned the first responder status or NO if it did not. 如果视图放弃了第一响应者状态,则为YES否则,则为NO

Discussion 讨论区
This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. 此方法查看当前视图及其子视图层次结构中当前是第一响应者的文本字段。 If it finds one, it asks that text field to resign as first responder. 如果找到一个,它将要求该文本字段辞去第一响应者的职务。 If the force parameter is set to YES , the text field is never even asked; 如果将force参数设置为YES ,则永远不会询问文本字段; it is forced to resign. 它被迫辞职。

This swift code works in finding the first responder: 此快速代码可用于查找第一个响应者:

func findActiveResponderFrame(view:UIView)->UIView?{
  if view.isFirstResponder() {
    return view
  } else {
    for sub in view.subviews {
      if let subView = sub as? UIView,
             found = findActiveResponderFrame(subView){
        return found
      }
    }
  }
  return nil
}

There is no way to directly get what object is the current first responder (that I know of, at least) without testing them individually. 如果没有单独测试它们,就无法直接获得当前的第一响应者(至少我知道)是什么对象。 What you can do is to create a method containing all subviews which could conceivably be the active first responder, as follows: 您可以做的是创建一个包含所有子视图的方法,可以将其视为活动的第一响应者,如下所示:

- (void)dismissKeyboard {
    if (myTextField1.isFirstResponder) {
        [myTextField1 resignFirstResponder];
    }
    else if (myTextField2.isFirstResponder) {
        [myTextField2 resignFirstResponder];
    }
    else if (myTextField3.isFirstResponder) {
        [myTextField3 resignFirstResponder];
    }
    else if (myTextField4.isFirstResponder) {
        [myTextField4 resignFirstResponder];
    }
}

In reality, though, I tend to do it this way, without first testing whether a particular UIView is the current first responder, and don't think there is any appreciable performance hit/issue (that I've noticed anyway): 但是,实际上,我倾向于以这种方式进行操作,而不先测试特定的UIView是否是当前的第一响应者,并且不认为有任何明显的性能问题(无论如何,我已经注意到):

- (void)dismissKeyboard {
    //Send resignFirstResponder message to all possible first responders...
    [myTextField1 resignFirstResponder];
    [myTextField2 resignFirstResponder];
    [myTextField3 resignFirstResponder];
    [myTextField4 resignFirstResponder];
}

Hope that helps... 希望有帮助...

Update for Swift 3 Swift 3更新

This function hides the keyboard of any active textfield in Swift 3: 此功能可隐藏Swift 3中任何活动文本字段的键盘:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
}

Similar question posted here . 类似的问题在这里发布。 I wrote a basic form creation library that handles this and validation. 我写了一个基本的表单创建库来处理和验证。 It's called Swift POP Form ! 它叫做Swift POP Form It doesn't use tags but rather sets a datasource that contains fields and uses indexPathForCell to query which is the active textfield. 它不使用tags ,而是设置一个包含字段的数据源,并使用indexPathForCell来查询哪个是活动文本字段。 Check out the source code for more! 查看更多源代码!

edit: Or as requested heres a snippet from it. 编辑:或按要求从这里摘录。 This form uses UITextFields embedded in UITableViewCells : 此表单使用嵌入在UITableViewCells UITextFields

extension PopFormViewController: UITextFieldDelegate {

  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    guard let cell = textField.superview as? PopFormTableViewCell else {
      fatalError() }

    guard let currentIndex = tableView.indexPath(for: cell) else {
      fatalError("cell does not exist") }

    let nextIndex = IndexPath(row: currentIndex.row + 1, section: currentIndex.section)
    let isLastField = viewModel.dataSource.fields.count == nextIndex.row

    if isLastField {
      cell.textField.resignFirstResponder()
      if shouldValidateOnLastFieldReturnKeyTap {
        validator.validate(self)
      }
      return true
    }

    guard let nextCell = tableView.cellForRow(at: nextIndex) as? PopFormTableViewCell else {
      fatalError() }

    nextCell.textField.becomeFirstResponder()
    return true
  }
}

You can following if you specifically want to fetch responder text field. 如果您特别想获取响应者文本字段,则可以关注。 Get the current first responder without using a private API 在不使用私有API的情况下获取当前的第一响应者

you can also use following code if you only want to dismiss active text field keyboard- 如果您只想关闭活动的文本字段键盘,也可以使用以下代码-

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
   [textField resignFirstResponder];
   return YES;
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM