获取iOS键盘的高度而不显示键盘

我想获得iOS键盘的高度。 我已经经历了,并使用了订阅通知的方法,如在这里详细说明: https : //gist.github.com/philipmcdermott/5183731

- (void)viewDidAppear:(BOOL) animated { [super viewDidAppear:animated]; // Register notification when the keyboard will be show [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; // Register notification when the keyboard will be hide [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } - (void)keyboardWillShow:(NSNotification *)notification { CGRect keyboardBounds; [[notification.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBounds]; // Do something with keyboard height } - (void)keyboardWillHide:(NSNotification *)notification { CGRect keyboardBounds; [[notification.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBounds]; // Do something with keyboard height } 

这适用于用户实际显示键盘的情况。

我的问题:我有另一种观点,我们称之为micView,可能会出现在键盘出现之前。 用户可以在打字之前select使用麦克风。 我希望micView与键盘的高度相同,这就是为什么我需要键盘的高度,但是在键盘被迫出现之前我需要它。 因此,在我需要读取高度的值之前,UIKeyboardWillShowNotification没有达到。

我的问题是:如何通过Notifications或其他方法获得键盘的高度,而不会出现键盘。

我认为显式强制键盘出现在viewDidLoad,所以我可以设置一个实例variables的值,然后隐藏它,摆脱两者的animation。 但是,这真的是唯一的方法吗?

你可以使用的一个快速解决scheme,是当你想要caching键盘时使用的一个快速的解决scheme(第一次显示它,你会稍微延迟…)。 图书馆在这里 。 有趣的一点:

 [[[[UIApplication sharedApplication] windows] lastObject] addSubview:field]; [field becomeFirstResponder]; [field resignFirstResponder]; [field removeFromSuperview]; 

所以基本上是显示它,然后隐藏它。 你可以听取通知,只是得到height而没有真正看到它。 奖金 :你可以caching它。 🙂

这个Swift类提供了一个交钥匙解决scheme,可以pipe理所有必要的通知和初始化,让您只需调用一个类方法并返回键盘大小或高度。

从Swift调用:

 let keyboardHeight = KeyboardService.keyboardHeight() let keyboardSize = KeyboardService.keyboardSize() 

从Objective-C调用:

  CGFloat keyboardHeight = [KeyboardService keyboardHeight]; CGRect keyboardSize = [KeyboardService keyboardSize]; 

如果想要将其用于初始视图布局,请在出现键盘之前,根据需要键盘高度或大小的类的viewWillAppear方法调用此方法。 它不应该在viewDidLoad中调用,因为正确的值取决于您的视图。 然后,您可以使用从KeyboardService返回的值设置自动布局约束常量,或以其他方式使用该值。 例如,您可能希望在prepareForSegue获取键盘高度,以帮助设置与通过embeddedsegue填充的containerView的内容相关联的值。

注意安全区域,键盘高度和iPhone X
键盘高度的值返回键盘的全部高度,在iPhone X上它延伸到屏幕本身的边缘,而不仅仅是安全区域插入。 因此,如果使用返回值设置自动布局约束值,则应该将该约束附加到超级视图底部边缘,而不是安全区域。

注意模拟器中的硬件键盘
当连接硬件键盘时,此代码将提供该硬件键盘的屏幕高度,即无高度。 当然,这个状态确实需要考虑,因为这模拟了如果硬件键盘连接到实际设备上会发生什么。 因此,期望键盘高度的布局需要适当地响应零高的键盘高度。

KeyboardService类:
像往常一样,如果从Objective-C调用,只需要在Objective-C类中导入应用的Swift桥接头MyApp-Swift.h

 import UIKit class KeyboardService: NSObject { static var serviceSingleton = KeyboardService() var measuredSize: CGRect = CGRect.zero @objc class func keyboardHeight() -> CGFloat { let keyboardSize = KeyboardService.keyboardSize() return keyboardSize.size.height } @objc class func keyboardSize() -> CGRect { return serviceSingleton.measuredSize } private func observeKeyboardNotifications() { let center = NotificationCenter.default center.addObserver(self, selector: #selector(self.keyboardChange), name: .UIKeyboardDidShow, object: nil) } private func observeKeyboard() { let field = UITextField() UIApplication.shared.windows.first?.addSubview(field) field.becomeFirstResponder() field.resignFirstResponder() field.removeFromSuperview() } @objc private func keyboardChange(_ notification: Notification) { guard measuredSize == CGRect.zero, let info = notification.userInfo, let value = info[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return } measuredSize = value.cgRectValue } override init() { super.init() observeKeyboardNotifications() observeKeyboard() } deinit { NotificationCenter.default.removeObserver(self) } } 

点头:
这里的observeKeyboard方法基于Peres在Objective-C回答中提出的原始方法。