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.