如何以编程方式解除键盘?

时间:2012-01-21 21:09:55

标签: iphone ios ipad cocoa-touch uitextfield

我需要一种方法来确定当前在视图中选择的UITextField。这可能不通过引用或标记吗?

更具体地说,我需要能够分辨出哪个UITextField被选中,这样我才能隐藏键盘。我需要这个的原因是因为我想创建一个UIToolbar来添加到所有UITextField作为输入附件。在这个UIToolbar上我会添加一个“完成”按钮,按下此按钮会隐藏当前所选UITextField的键盘。

6 个答案:

答案 0 :(得分:1)

我认为你的意思是你想知道哪个UITextField是第一个响应者(这是从键盘输入的文本字段)。

此处没有公共API(尽管有私有API)。您可以使用每个文本字段的委托的textFieldDidBeginEditing:方法手动跟踪哪个文本字段是第一个响应者,或者您可以使用一些小技巧随时查找第一个响应者。

这就是诀窍。 UIApplication对象知道哪个对象是第一个响应者,并且可以向其发送消息。所以你在UIResponder上写了这样一个类别:

UIResponder + firstResponderHack.h

#import <UIKit/UIKit.h>

@interface UIResponder (firstResponderHack)

+ (UIResponder *)firstResponderByHack;

@end

UIResponder + firstResponderHack.m

#import "UIResponder+firstResponderHack.h"

@interface FirstResponderFinder : NSObject
@property (strong, nonatomic) UIResponder *firstResponder;
@end

@implementation FirstResponderFinder
@synthesize firstResponder = _firstResponder;
@end

@implementation UIResponder (firstResponderHack)

- (void)putFirstResponderIntoFinder:(FirstResponderFinder *)finder {
    if (self.isFirstResponder)
        finder.firstResponder = self;
}

+ (UIResponder *)firstResponderByHack {
    FirstResponderFinder *finder = [FirstResponderFinder new];
    // Sending an action to nil sends it to the first responder.
    [[UIApplication sharedApplication] sendAction:@selector(putFirstResponderIntoFinder:) to:nil from:finder forEvent:nil];
    return finder.firstResponder;
}

@end

然后你可以找到第一个响应者,并检查它是否是UITextField,如下所示:

UIResponder *firstResponder = [UIResponder firstResponderByHack];
if (firstResponder && [firstResponder isKindOfClass:[UITextField class]]) {
    UITextField *textField = (UITextField *)firstResponder;
    // do something with textField
}

答案 1 :(得分:1)

有一种简单的方法可以解除键盘,而无需跟踪当前活动的控件,或者遍历所有可用的控件,或使用UITextFieldDelegate

[self.view endEditing:YES]

来自文档:

  

endEditing:

     

使视图(或其中一个嵌入的文本字段)成为   辞去第一响应者的身份。

       - (BOOL)endEditing:(BOOL强制

     

<强>参数
  
  指定YES以强制第一响应者辞职,无论其是否愿意   所以。

  返回值
  YES如果视图已退出第一响应者状态,或NO如果不是。{

     

<强>讨论
  此方法查看当前视图及其子视图   当前第一个响应者的文本字段的层次结构。如果   它找到一个,它要求文本字段作为第一响应者辞职。如果   force参数设置为YES,文本字段永远不会被询问;   它被迫辞职。

答案 2 :(得分:0)

有委托方法:

- (void)textFieldDidBeginEditing:(UITextField *)textField

Apple Docs:

  

此方法仅通知委托指定的文本字段   成为第一个响应者。您可以使用此方法更新您的   代表的国家信息。例如,您可以使用此方法   显示编辑时应该可见的叠加视图。

还有一个属性:

@property(nonatomic, readonly, getter=isEditing) BOOL editing

Apple Docs:

  

一个布尔值,指示文本字段当前是否处于编辑状态   模式。 (只读)

答案 3 :(得分:0)

只需在头文件中为UITextView制作一个ivar:

UITextField *editingField;
@property (nonatomic, copy) UITextField *editingField;

然后,

- (void)textFieldDidBeginEditing:(UITextField *)textField;
{
    editingField = textField;

    // Whatever else you want to do 
}

答案 4 :(得分:0)

我认为您需要在没有引用的情况下区分textFields。 因此,建议使用 ObjectiveC运行时的原因 它很直接。 首先:

  #import <objc/runtime.h>

然后,为其地址定义一个char:

   static char UITextFieldViewIdentifier;

然后使用以下内容设置标识符:

  objc_setValue(textField, &UITextFieldViewIdentifier, @"Identifier") //typing on a phone, not so sure about the expression

在委托方法中:

   NSString *identifier = objc_getObject(textField, &UITextFieldViewIdentifier)

答案 5 :(得分:0)

只需将此行调用到您要关闭键盘的位置:

[self.view endEditing:YES];