是否可以获取与键盘关联的文本字段?

Is it possible to get textfield assosiated with a keyboard?

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

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

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

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

You should use UITextField delegate function 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
}

只有一种手动方式

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

Swift

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

有更好的方法可以通过开始编辑 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
    }
}

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

Implement the UITextFieldDelegate delegate method textFieldShouldBeginEditing:textField

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

Store the UITextField that received this delegate call to be referenced when determining which field triggered this event.


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

- (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];

}