我需要检查iOS应用中键盘可见性的状况.
伪代码:
if(keyboardIsPresentOnWindow) { //Do action 1 } else if (keyboardIsNotPresentOnWindow) { //Do action 2 }
我该如何检查这种情况?
......或采取简单的方法:
当您输入textField时,它将成为第一响应者并出现键盘.您可以使用检查键盘的状态[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
创建一个UIKeyboardListener
当你知道键盘是不可见的,例如通过调用[UIKeyboardListener shared]
从applicationDidFinishLaunching
.
@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
键盘通知
当系统显示或隐藏键盘时,它会发布几个键盘通知.这些通知包含有关键盘的信息,包括其大小,您可以将其用于涉及移动视图的计算.注册这些通知是获取有关键盘的某些类型信息的唯一方法.系统为键盘相关事件提供以下通知:
* UIKeyboardWillShowNotification * UIKeyboardDidShowNotification * UIKeyboardWillHideNotification * UIKeyboardDidHideNotification有关这些通知的详细信息,请参阅UIWindow类参考中的说明.有关如何显示和隐藏键盘的信息,请参阅文本和Web.
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 } }
使用窗口子视图层次结构作为键盘显示的指示是一种黑客攻击.如果Apple改变他们的基础实现,所有这些答案都会破裂.
正确的方法是监控键盘显示和隐藏应用程序范围内的通知,例如在App Delegate中:
在AppDelegate.h中:
@interface AppDelegate : UIResponder@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;
应该注意,当用户使用蓝牙或外部键盘时,键盘显示/隐藏通知不会触发.
现在在iOS8中,这个解决方案当然不起作用.它最初是为IOS4/5编写的.
尝试此解决方案:
- (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; }
这是Apple发布的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; }
添加扩展
extension UIApplication { /// Checks if view hierarchy of application contains `UIRemoteKeyboardWindow` if it does, keyboard is presented var isKeyboardPresented: Bool { if let keyboardWindowClass = NSClassFromString("UIRemoteKeyboardWindow"), self.windows.contains(where: { $0.isKind(of: keyboardWindowClass) }) { return true } else { return false } } }
然后检查是否有键盘,
if UIApplication.shared.isKeyboardPresented { print("Keyboard presented") } else { print("Keyboard is not presented") }