如何以编程方式检查iphone应用程序中是否存在键盘?

我需要检查我的iPhone应用程序的键盘可见性的条件。

喜欢:

if(keyboardIsPresentOnWindow) { //Do action 1 } else if (keyboardIsNotPresentOnWindow) { //Do action 2 } 

我怎样才能检查这种情况?

…或采取简单的方法:

当你input一个文本字段时,它将成为第一个响应者,并出现键盘。 您可以使用[myTextField isFirstResponder]来检查键盘的状态。 如果返回YES ,则键盘处于活动状态。

drawnonward的代码是非常接近的,但与UIKit的命名空间相冲突,可以更容易使用。

 @interface KeyboardStateListener : NSObject { BOOL _isVisible; } + (KeyboardStateListener *)sharedInstance; @property (nonatomic, readonly, getter=isVisible) BOOL visible; @end static KeyboardStateListener *sharedInstance; @implementation KeyboardStateListener + (KeyboardStateListener *)sharedInstance { return sharedInstance; } + (void)load { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; sharedInstance = [[self alloc] init]; [pool release]; } - (BOOL)isVisible { return _isVisible; } - (void)didShow { _isVisible = YES; } - (void)didHide { _isVisible = NO; } - (id)init { if ((self = [super init])) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(didShow) name:UIKeyboardDidShowNotification object:nil]; [center addObserver:self selector:@selector(didHide) name:UIKeyboardWillHideNotification object:nil]; } return self; } @end 

如果知道键盘不可见,则创build一个UIKeyboardListener ,例如通过调用[UIKeyboardListener shared]

 @implementation UIKeyboardListener + (UIKeyboardListener) shared { static UIKeyboardListener sListener; if ( nil == sListener ) sListener = [[UIKeyboardListener alloc] init]; return sListener; } -(id) init { self = [super init]; if ( self ) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(noticeShowKeyboard:) name:UIKeyboardDidShowNotification object:nil]; [center addObserver:self selector:@selector(noticeHideKeyboard:) name:UIKeyboardWillHideNotification object:nil]; } return self; } -(void) noticeShowKeyboard:(NSNotification *)inNotification { _visible = true; } -(void) noticeHideKeyboard:(NSNotification *)inNotification { _visible = false; } -(BOOL) isVisible { return _visible; } @end 

我认为你需要使用关于键盘提供的通知:

来自: http : //developer.apple.com/iphone/library/documentation/UIKit/Reference/UITextField_Class/Reference/UITextField.html

键盘通知

当系统显示或隐藏键盘时,会发出几个键盘通知。 这些通知包含有关键盘的信息,包括其大小,可用于涉及移动视图的计算。 注册这些通知是获取有关键盘的某些types信息的唯一方法。 系统为键盘相关事件提供以下通知:

 * UIKeyboardWillShowNotification * UIKeyboardDidShowNotification * UIKeyboardWillHideNotification * UIKeyboardDidHideNotification 

有关这些通知的更多信息,请参阅UIWindow类参考中的说明。 有关如何显示和隐藏键盘的信息,请参阅文本和Web。

使用窗口子视图层次作为键盘显示的指示是一种破解。 如果苹果改变了他们的基础实现,所有这些答案将会中断。

正确的方法是监视键盘显示和隐藏通知应用程序范围内,如在您的应用程序委托:

在AppDelegate.h中:

 @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (assign, nonatomic) BOOL keyboardIsShowing; @end 

在AppDelegate.m中:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Monitor keyboard status application wide self.keyboardIsShowing = NO; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; return YES; } - (void)keyboardWillShow:(NSNotification*)aNotification { self.keyboardIsShowing = YES; } - (void)keyboardWillBeHidden:(NSNotification*)aNotification { self.keyboardIsShowing = NO; } 

那么你可以检查使用:

 BOOL keyboardIsShowing = ((AppDelegate*)[UIApplication sharedApplication].delegate).keyboardIsShowing; 

应该注意,当用户使用蓝牙或外部键盘时,键盘显示/隐藏通知不会被触发。

Swift 3实现

  import Foundation class KeyboardStateListener: NSObject { static let shared = KeyboardStateListener() var isVisible = false func start() { NotificationCenter.default.addObserver(self, selector: #selector(didShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(didHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func didShow() { isVisible = true } func didHide() { isVisible = false } } 

这是从苹果发布的iOS文本编程指南这里: https : //developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

基本上在你的ViewDidLoad中调用“registerForKeyBoardNotifications”。 然后每次键盘激活时,都会调用“keyboardWasShown”。 每当键盘消失,“keyboardWillBeHidden”被调用。

 // Call this method somewhere in your view controller setup code. - (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; } // Called when the UIKeyboardDidShowNotification is sent. - (void)keyboardWasShown:(NSNotification*)aNotification { NSLog(@"Keyboard is active."); NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; // If active text field is hidden by keyboard, scroll it so it's visible // Your app might not need or want this behavior. CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) { [self.scrollView scrollRectToVisible:activeField.frame animated:YES]; } } // Called when the UIKeyboardWillHideNotification is sent - (void)keyboardWillBeHidden:(NSNotification*)aNotification { NSLog(@"Keyboard is hidden"); UIEdgeInsets contentInsets = UIEdgeInsetsZero; scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; } 

现在在iOS8中,这个解决scheme当然不起作用。 它最初是为IOS4 / 5编写的。

试试这个解决scheme

 - (BOOL) isKeyboardOnScreen { BOOL isKeyboardShown = NO; NSArray *windows = [UIApplication sharedApplication].windows; if (windows.count > 1) { NSArray *wSubviews = [windows[1] subviews]; if (wSubviews.count) { CGRect keyboardFrame = [wSubviews[0] frame]; CGRect screenFrame = [windows[1] frame]; if (keyboardFrame.origin.y+keyboardFrame.size.height == screenFrame.size.height) { isKeyboardShown = YES; } } } return isKeyboardShown; } 

几点意见:

推荐的单体对象模式如下。 dispatch_once确保类以线程安全的方式初始化一次,并且静态variables在外部不可见。 而且它是标准的GCD,所以不需要了解Objective-C的低级细节。

 + (KeyboardStateListener *)sharedInstance { static KeyboardStateListener* shared; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ shared = [[KeyboardStateListener alloc] init]; // Other initialisations }); return shared; } 

通常你不想知道键盘是否可见,但是它有多大。 键盘并不都具有相同的大小。 iPhone键盘比iPad键盘更小。 所以你想要另一个属性@property (readonly, nonatomic) CGRect keyboardRect; 这是在noticeShowKeyboard:方法中设置的:

 NSValue* value = notification.userInfo [UIKeyboardFrameEndUserInfoKey]; _keyboardRect = value.CGRectValue; 

重要的是要注意,该矩形是在UIWindow坐标,并不尊重屏幕旋转。 所以调用者会通过调用来转换矩形

 KeyboardStateListener* listener = [KeyboardStateListener sharedInstance]; CGRect windowRect = listener.keyboardRect; CGRect viewRect = [myView convertRect:windowRect fromView:self.window]; 

如果用户在键盘可见的情况下旋转屏幕,则应用程序会被告知键盘已隐藏,然后再次显示。 显示时,其他视图最有可能不旋转。 因此,如果您自己观察键盘隐藏/显示事件,请在实际需要时转换坐标,而不是在通知中。

如果用户拆分或取消键盘,或使用硬件键盘,则通知将始终将键盘显示为隐藏。 拆卸或合并键盘将发送“键盘显示”通知。

监听器必须在键盘被隐藏的时候被初始化,否则第一个通知将被忽略,并且假定键盘被隐藏。

所以知道你真正想要什么是非常重要的。 这段代码对于将事情从键盘移开(使用分离或未连接的键盘,这是用户的责任)非常有用。 它不会告诉您用户是否可以在屏幕上看到键盘(如果是分离键盘)。 它不会告诉您用户是否可以键入(例如,当有硬件键盘时)。 如果应用程序本身创build其他窗口,查看其他窗口不起作用。

这里是如何在Swift中完成的:

  func registerForKeyboardNotifications() { NSNotificationCenter.defaultCenter().addObserver( self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver( self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil) } func keyboardWasShown(notification: NSNotification) { println("Keyboard was shown"); } func keyboardWillBeHidden(notification: NSNotification) { println("Keyboard was dismissed"); } 

不要忘记取消注册:

  override func viewWillDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardDidShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) } 

如果你想按下“返回”button来closures键盘:

 class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var yourTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() registerForKeyboardNotifications() yourTextField.delegate = self } func textFieldShouldReturn(textField: UITextField!) -> Bool { self.view.endEditing(true); return false; } } 

快速实施:

 class KeyboardStateListener: NSObject { static var shared = KeyboardStateListener() var isVisible = false func start() { let nc = NSNotificationCenter.defaultCenter() nc.addObserver(self, selector: #selector(didShow), name: UIKeyboardDidShowNotification, object: nil) nc.addObserver(self, selector: #selector(didHide), name: UIKeyboardDidHideNotification, object: nil) } func didShow() { isVisible = true } func didHide() { isVisible = false } } 

由于swift在启动时不执行类加载方法,因此在启动应用程序时启动此服务非常重要:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool { ... KeyboardStateListener.shared.start() } 

试试这个function

 BOOL UIKeyboardIsVisible(){ BOOL keyboardVisible=NO; // Locate non-UIWindow. UIWindow *keyboardWindow = nil; for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { if (![[testWindow class] isEqual:[UIWindow class]]) { keyboardWindow = testWindow; break; } } // Locate UIKeyboard. for (UIView *possibleKeyboard in [keyboardWindow subviews]) { // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView. if ([[possibleKeyboard description] hasPrefix:@"<UIPeripheralHostView"]) { keyboardVisible=YES; } if ([[possibleKeyboard description] hasPrefix:@"<UIKeyboard"]) { keyboardVisible=YES; break; } } return keyboardVisible; 

}

来自: iOS:如何访问“UIKeyboard”?

BOOL isTxtOpen = [txtfieldObjct isFirstReponder]。 如果返回YES,则键盘处于活动状态。

要检查天气键盘是否出现,我们可以使用键盘预定义的通知。

UIKeyboardDidShowNotification,UIKeyboardDidHideNotification

例如,我可以使用下面的代码来收听键盘通知

//听键盘出现和失踪

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil]; 

在方法中我可以得到通知

 - (void)keyboardDidShow: (NSNotification *) notifyKeyBoardShow{ // key board is closed } - (void)keyboardDidHide: (NSNotification *) notifyKeyBoardHide{ // key board is opened } 

这是我的解决scheme,它将所有内容封装到一个静态方法中,您可以在任何地方调用它来检查:

 +(BOOL)isKeyboardVisible{ static id tokenKeyboardWillShow = nil; static id tokenKeyboardWillHide = nil; static BOOL isKbVisible = NO; @synchronized (self) { if (tokenKeyboardWillShow == nil){ tokenKeyboardWillShow = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { @synchronized (self) { isKbVisible = YES; } }]; } if (tokenKeyboardWillHide == nil){ tokenKeyboardWillHide = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { @synchronized (self) { isKbVisible = NO; } }]; } } return isKbVisible; } 

我认为这可能会帮助你,

 +(BOOL)isKeyBoardInDisplay { BOOL isExists = NO; for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) { if ([[keyboardWindow description] hasPrefix:@"<UITextEffectsWindow"] == YES) { isExists = YES; } } return isExists; } 

谢谢,

纳文珊