【问题标题】:Is it possible to get textfield assosiated with a keyboard?是否可以获取与键盘关联的文本字段?
【发布时间】:2015-11-06 00:37:06
【问题描述】:

在我的视图控制器中,我订阅了UIKeyboardWillShowNotification

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

所以在我的keyboardWillShow: 方法中,我可以从通知中检索有关键盘的一些信息。但我想要的是获得对启动键盘的实际文本字段的引用。我在谷歌中找不到如何做到这一点,我怀疑这可能是不可能的,但有人可能知道。如果确实不可能,那么我想知道是否有可能使其反向 - 通过引用文本字段来获取有关键盘的信息。谢谢

【问题讨论】:

  • 你应该使用UITextField delegate函数textFieldShouldBeginEditing:当你的键盘出现时这个委托函数会被调用,并保存这个函数的UITextField引用?
  • 是的,我当然知道,但在当前架构中对我来说并不方便。如果我没有找到其他任何东西,我将使用这种方法作为最后的手段
  • 我希望我可以为@iphonic 添加+2:只有textFieldShouldBeginEditing: 有效。 keyboardWillShow 不稳定,不能与硬件键盘(蓝牙,iPad 上常见)一起使用
  • @iphonic 100% 正确。谢谢!

标签: ios objective-c cocoa-touch uitextfield uikit


【解决方案1】:

让我强调@iphonic 评论是正确的方法。

你应该使用UITextField委托函数textFieldShouldBeginEditing:

任何不足之处都是一团糟:UIKeyboardWillShowNotification 假设软件键盘会出现,这是一个非常危险的假设,并且在各种情况下可能会失败,开始但不是仅限于蓝牙键盘。 在模拟器中试试 cmd-K。

这是前面提到的 kludge,灵感来自 Get the current first responder without using a private API

func keyboardWillShow() {
    let firstResponder = self.findFirstResponder(inView: self.view)
    println("keyboardWillShow for \(firstResponder)")
}

func findFirstResponder(inView view: UIView) -> UIView? {
    for subView in view.subviews as! [UIView] {
        if subView.isFirstResponder() {
            return subView
        }

        if let recursiveSubView = self.findFirstResponder(inView: subView) {
            return recursiveSubView
        }
    }

    return nil
}

【讨论】:

    【解决方案2】:

    只有一种手动方式

    if ([firstName isFirstResponder]) {
        // caused due to firstName
    } else if ([lastName isFirstResponder]) {
        // caused due to lastName
    }
    

    斯威夫特

    if firstName.isFirstResponder { // caused due to firstName } 
    else
    if lastName.isFirstResponder { // caused due to lastName }
    

    【讨论】:

    • 如果你提前知道你的响应者,那么代码肯定会更少,例如在动态单元格中。
    • 添加 swift 3 支持: if firstName.isFirstResponder { // 由于 firstName 导致 } else if lastName.isFirstResponder { // 由于 lastName 导致 }
    【解决方案3】:

    通过确实开始编辑UITextFieldUITextView 的通知,有更好的方法来做到这一点:

    UITextFieldTextDidBeginEditingNotification

    UITextViewTextDidBeginEditingNotification

    - (void)startListeningForKeyboardNotification {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(responderDidBeginEditing:) name:UITextFieldTextDidBeginEditingNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(responderDidBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:nil];
    }
    
    - (void)responderDidBeginEditing:(NSNotification *)notification {
        if ([notification.object isKindOfClass:[UITextField class]]) {
            UITextField *textField = notification.object;
            // Do something with text field
        } else if ([notification.object isKindOfClass:[UITextView class]]) {
            UITextView *textView = notification.object;
            // Do something with text view
        }
    }
    

    【讨论】:

      【解决方案4】:

      最简单(也是几乎唯一)的方法恰好也是最佳方法(如@iphonic 所述)

      实现UITextFieldDelegate委托方法textFieldShouldBeginEditing:textField

      此方法将在任何其他事件之前调用(包括任何键盘通知)

      存储收到此委托调用的UITextField,以便在确定哪个字段触发此事件时引用。


      我还建议您做的是,如果您要确定哪个键盘触发了当前键盘外观,此委托方法只需注册以接收键盘通知。

      - (BOOL)textFieldShouldBeginEditing:(UITextView *)textView {
      
          [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
      
          return YES;
      
      }
      

      这样,您可以确定当keyboardWillShow: 被调用时,它实际上是从这个特定的文本字段触发的。

      当然,为了确保正确跟踪文本字段,请在文本字段停止编辑时停止收听。

      - (void)textFieldDidEndEditing:(UITextView *)textView {
      
          [NSNotificationCenter.defaultCenter removeObserver:self name:UIKeyboardWillShowNotification object:nil];
      
      }
      

      【讨论】:

        猜你喜欢
        • 2018-06-15
        • 2021-10-25
        • 2014-10-17
        • 1970-01-01
        • 2012-11-20
        • 1970-01-01
        • 2013-08-11
        • 2014-10-12
        • 1970-01-01
        相关资源
        最近更新 更多