Objective c 如果键盘是';它已经显示了吗?

Objective c 如果键盘是';它已经显示了吗?,objective-c,cocoa-touch,Objective C,Cocoa Touch,我有一个自定义的UITextField类,它需要在键盘显示后抓取它的rect。因此,在课堂上,我聆听UIKeyboardWillShowNotification,并从UIKeyboardFrameEndUserInfoKey抓取键盘的rect。如果当前未显示键盘,则此操作非常有效。但是,如果键盘已经显示,例如在文本字段之间点击时,UIKeyboardWillShowNotification只会在点击第一个文本字段时触发。对于其他文本字段,我无法知道键盘的rect是什么 在键盘显示后,有没有关于如

我有一个自定义的
UITextField
类,它需要在键盘显示后抓取它的rect。因此,在课堂上,我聆听
UIKeyboardWillShowNotification
,并从
UIKeyboardFrameEndUserInfoKey
抓取键盘的rect。如果当前未显示键盘,则此操作非常有效。但是,如果键盘已经显示,例如在文本字段之间点击时,
UIKeyboardWillShowNotification
只会在点击第一个文本字段时触发。对于其他文本字段,我无法知道键盘的rect是什么


在键盘显示后,有没有关于如何获取它的rect的建议?

给你的
AppDelegate
一个
keyboardFrame
属性。使
AppDelegate
遵守
UIKeyboardWillShowNotification
UIKeyboardWillHideNotification
并适当更新属性。隐藏键盘时,将属性设置为
CGRectNull
,或添加单独的
keyboardIsShowing
属性。(您可以使用
CGRectIsNull
函数测试
CGRectIsNull

然后,任何对象都可以随时使用此咒语检查键盘框架:

[[UIApplication sharedApplication].delegate keyboardFrame]
如果你不想把它放到你的应用程序委托中,你可以创建一个单独的单例类,例如

@interface KeyboardProxy

+ (KeyboardProxy *)sharedProxy;

@property (nonatomic, readonly) CGRect frame;
@property (nonatomic, readonly) BOOL visible;

@end

@implementation KeyboardProxy

#pragma mark - Public API

+ (KeyboardProxy *)sharedProxy {
    static dispatch_once_t once;
    static KeyboardProxy *theProxy;
    dispatch_once(&once, ^{
        theProxy = [[self alloc] init];
    });
    return theProxy;
}

@synthesize frame = _frame;

- (BOOL)visible {
    return CGRectIsNull(self.frame);
}

#pragma mark - Implementation details

- (id)init {
    if (self = [super init]) {
        _frame = CGRectNull;
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    return self;
}

- (void)keyboardWillShow:(NSNotification *)note {
    _frame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
}

- (void)keyboardWillHide:(NSNotification *)note {
    _frame = CGRectNull;
}

@end

但是如果您使用单独的单例程序,您需要确保从应用程序代理的
应用程序调用
[KeyboardProxy sharedProxy]
:使用选项完成启动:
,这样单例程序就不会错过任何通知。

给您的
AppDelegate
一个
keyboardFrame
属性。使
AppDelegate
遵守
UIKeyboardWillShowNotification
UIKeyboardWillHideNotification
并适当更新属性。隐藏键盘时,将属性设置为
CGRectNull
,或添加单独的
keyboardIsShowing
属性。(您可以使用
CGRectIsNull
函数测试
CGRectIsNull

然后,任何对象都可以随时使用此咒语检查键盘框架:

[[UIApplication sharedApplication].delegate keyboardFrame]
如果你不想把它放到你的应用程序委托中,你可以创建一个单独的单例类,例如

@interface KeyboardProxy

+ (KeyboardProxy *)sharedProxy;

@property (nonatomic, readonly) CGRect frame;
@property (nonatomic, readonly) BOOL visible;

@end

@implementation KeyboardProxy

#pragma mark - Public API

+ (KeyboardProxy *)sharedProxy {
    static dispatch_once_t once;
    static KeyboardProxy *theProxy;
    dispatch_once(&once, ^{
        theProxy = [[self alloc] init];
    });
    return theProxy;
}

@synthesize frame = _frame;

- (BOOL)visible {
    return CGRectIsNull(self.frame);
}

#pragma mark - Implementation details

- (id)init {
    if (self = [super init]) {
        _frame = CGRectNull;
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    return self;
}

- (void)keyboardWillShow:(NSNotification *)note {
    _frame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
}

- (void)keyboardWillHide:(NSNotification *)note {
    _frame = CGRectNull;
}

@end

但是如果您使用单独的单例,您需要确保从应用程序代理的
应用程序调用
[KeyboardProxy sharedProxy]
:didFinishLaunchingWithOptions:
,这样单例就不会错过任何通知。

为rect创建一个属性,并在键盘第一次出现时设置该属性的值。为rect创建一个属性,并在键盘第一次出现时设置该属性的值。-1:应用程序委托应仅用于初始设置。相反,如果你想要一个共享对象,单例更好。应用程序委托是单例。为什么还要创建另一个呢?请注意,在任何其他代码出现键盘之前,您必须初始化另一个单例。应用程序代理的
应用程序:didFinishLaunchingWithOptions:
是执行此操作的适当位置。所以无论如何,应用程序代理都需要参与。@jrgdeveloper我同意你的看法。委托不应该用于这种类型的事情。虽然大多数开发人员都是为了方便起见,但我尽可能避免使用它。@robmayoff我同意,无论是将属性放置在
AppDelegate
中,还是创建一个从AppDelegate初始化的单例,这都是一个相当挑剔的区别,但我认为这是一个重要的区别。不过,不值得否决这个答案+1.-1:应用程序代理只能用于初始设置。相反,如果你想要一个共享对象,单例更好。应用程序委托是单例。为什么还要创建另一个呢?请注意,在任何其他代码出现键盘之前,您必须初始化另一个单例。应用程序代理的
应用程序:didFinishLaunchingWithOptions:
是执行此操作的适当位置。所以无论如何,应用程序代理都需要参与。@jrgdeveloper我同意你的看法。委托不应该用于这种类型的事情。虽然大多数开发人员都是为了方便起见,但我尽可能避免使用它。@robmayoff我同意,无论是将属性放置在
AppDelegate
中,还是创建一个从AppDelegate初始化的单例,这都是一个相当挑剔的区别,但我认为这是一个重要的区别。不过,不值得否决这个答案+1.