ios 无法在 iOS8 中获得正确的键盘高度值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25874975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:30:19  来源:igfitidea点击:

can't get correct value of keyboard height in iOS8

iosobjective-ccocoa-touchkeyboardios8

提问by Eli Braginskiy

I was using this code to determine what is the size of the keyboard :

我正在使用此代码来确定键盘的大小:

- (void)keyboardWillChange:(NSNotification *)notification {
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];

}

I'm running this in the simulator.

我在模拟器中运行它。

The problem is since iOS 8 this will not give the correct value, if the keyboard suggestions is up or if I push them down I get different (not correct) values.

问题是因为 iOS 8 这不会给出正确的值,如果键盘建议是向上的,或者如果我按下它们,我会得到不同的(不正确的)值。

How can I get the exact size of the keyboard including the keyboard suggestions?

如何获得键盘的确切尺寸,包括键盘建议?

回答by dgangsta

With the introduction of custom keyboards in iOS, this problem becomes a tad more complex.

随着 iOS 中自定义键盘的引入,这个问题变得有点复杂。

In short, the UIKeyboardWillShowNotificationcan get called multiple times by custom keyboard implementations:

简而言之,自定义键盘实现可以多次调用UIKeyboardWillShowNotification

  1. When the Apple systemkeyboard is opened (in portrait)
    • UIKeyboardWillShowNotification is sent with a keyboard height of 224
  2. When the Swype keyboardis opened (in portrait):
    • UIKeyboardWillShowNotification is sent with a keyboard height of 0
    • UIKeyboardWillShowNotification is sent with a keyboard height of 216
    • UIKeyboardWillShowNotification is sent with a keyboard height of 256
  3. When the SwiftKey keyboardis opened (in portrait):
    • UIKeyboardWillShowNotification is sent with a keyboard height of 0
    • UIKeyboardWillShowNotification is sent with a keyboard height of 216
    • UIKeyboardWillShowNotification is sent with a keyboard height of 259
  1. Apple 系统键盘打开时(纵向)
    • UIKeyboardWillShowNotification 发送时键盘高度为224
  2. Swype 键盘打开时(纵向):
    • UIKeyboardWillShowNotification 发送时键盘高度为0
    • UIKeyboardWillShowNotification 发送时键盘高度为216
    • UIKeyboardWillShowNotification 发送时键盘高度为256
  3. SwiftKey 键盘打开时(纵向):
    • UIKeyboardWillShowNotification 发送时键盘高度为0
    • UIKeyboardWillShowNotification 发送时键盘高度为216
    • UIKeyboardWillShowNotification 发送时键盘高度为259

In order to handle these scenarios properly in one code-line, you need to:

为了在一个代码行中正确处理这些场景,您需要:

Register observers against the UIKeyboardWillShowNotificationand UIKeyboardWillHideNotificationnotifications:

针对UIKeyboardWillShowNotificationUIKeyboardWillHideNotification通知注册观察者:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];    
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];

Create a global variable to track the current keyboard height:

创建一个全局变量来跟踪当前的键盘高度:

CGFloat _currentKeyboardHeight = 0.0f;

Implement keyboardWillShowto react to the current change in keyboard height:

实现keyboardWillShow以响应当前键盘高度的变化:

- (void)keyboardWillShow:(NSNotification*)notification {
   NSDictionary *info = [notification userInfo];
   CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
   CGFloat deltaHeight = kbSize.height - _currentKeyboardHeight; 
   // Write code to adjust views accordingly using deltaHeight
   _currentKeyboardHeight = kbSize.height;
}

NOTE: You may wish to animate the offsetting of views. The infodictionary contains a value keyed by UIKeyboardAnimationDurationUserInfoKey. This value can be used to animate your changes at the same speed as the keyboard being displayed.

注意:您可能希望为视图偏移设置动画。该信息字典包含键的值UIKeyboardAnimationDurationUserInfoKey。此值可用于以与显示键盘相同的速度为您的更改设置动画。

Implement keyboardWillHideto the reset _currentKeyboardHeight and react to the keyboard being dismissed:

keyboardWillHide实现为重置的 _currentKeyboardHeight 并对被解除的键盘做出反应:

- (void)keyboardWillHide:(NSNotification*)notification {
   NSDictionary *info = [notification userInfo];
   CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
   // Write code to adjust views accordingly using kbSize.height
   _currentKeyboardHeight = 0.0f;
}

回答by souvickcse

Use

NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameEndUserInfoKey];

回答by Mike Gledhill

I also had this issue, until I came across this StackOverflowarticle:

我也有这个问题,直到我遇到这篇StackOverflow文章:

Convert UIKeyboardFrameEndUserInfoKey

转换 UIKeyboardFrameEndUserInfoKey

This shows you how to use the convertRectfunction, to convert the keyboard's size into something usable, but on the screen orientation.

这将向您展示如何使用该convertRect功能,将键盘的大小转换为可用的大小,但在屏幕方向上。

NSDictionary* d = [notification userInfo];
CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
r = [myView convertRect:r fromView:nil];

Previously, I had an iPad app which used UIKeyboardFrameEndUserInfoKeybut didn'tuse convertRect, and it worked fine.

以前,我有一个 iPad 应用程序,它使用UIKeyboardFrameEndUserInfoKey没有使用convertRect,并且运行良好。

But with iOS 8, it no longer worked properly. Suddenly, it would report that my keyboard, running on an iPad in landscape mode, was 1024 pixels high.

但是在 iOS 8 中,它不再正常工作。突然,它会报告我的键盘在 iPad 上以横向模式运行,高度1024 像素

So now, with iOS 8, it's essential that you use this convertRectfunction.

所以现在,在 iOS 8 中,使用这个convertRect功能是必不可少的。

回答by Avt

The similar to dgangsta'ssolution written in Swift 2.0:

类似于dgangsta用 Swift 2.0 编写解决方案:

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    guard let kbSizeValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
    guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return }
    animateToKeyboardHeight(kbSizeValue.CGRectValue().height, duration: kbDurationNumber.doubleValue)
}

func keyboardWillHide(notification: NSNotification) {
    guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return }
    animateToKeyboardHeight(0, duration: kbDurationNumber.doubleValue)
}

func animateToKeyboardHeight(kbHeight: CGFloat, duration: Double) {
    // your custom code here
}

回答by Wanbok Choi

I make extensionfor UIViewController

extensionUIViewController

extension UIViewController {
    func keyboardWillChangeFrameNotification(notification: NSNotification, scrollBottomConstant: NSLayoutConstraint) {
        let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
        let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber
        let keyboardBeginFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()
        let keyboardEndFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()

        let screenHeight = UIScreen.mainScreen().bounds.height
        let isBeginOrEnd = keyboardBeginFrame.origin.y == screenHeight || keyboardEndFrame.origin.y == screenHeight
        let heightOffset = keyboardBeginFrame.origin.y - keyboardEndFrame.origin.y - (isBeginOrEnd ? bottomLayoutGuide.length : 0)

        UIView.animateWithDuration(duration.doubleValue,
            delay: 0,
            options: UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16)),
            animations: { () in
                scrollBottomConstant.constant = scrollBottomConstant.constant + heightOffset
                self.view.layoutIfNeeded()
            },
            completion: nil
        )
    }
}

You can use like this :

你可以这样使用:

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChangeFrameNotification:", name: UIKeyboardWillChangeFrameNotification, object: nil)
}

...

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillChangeFrameNotification(notification: NSNotification) {
    self.keyboardWillChangeFrameNotification(notification, scrollBottomConstant: inputContainerBottom)
    // Write more to here if you want.
}

回答by Travis M.

There are times when devs need to know the keyboard height before it's actually shown, allowing them pre-layout the interface appropriately.

有时开发人员需要在实际显示之前知道键盘高度,以便他们适当地预先布局界面。

If that's the case, here's an inclusive spec:

如果是这种情况,这里有一个包容性规范:

enter image description here

在此处输入图片说明

This includes the quick type bar at the top, since that is on by default in all current versions of iOS.

这包括顶部的快速输入栏,因为它在所有当前版本的 iOS 中默认处于打开状态。

Here is the swift 3 notification setup I used to test this, if anyone needs it:

这是我用来测试的 swift 3 通知设置,如果有人需要的话:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
}

func keyboardWillShow(notification: NSNotification) {
    guard let keyboardSize = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
    print("\(keyboardSize)")
}

回答by Petr Syrov

Only one string for swift:

swift 只有一个字符串:

let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size

UIKeyboardFrameEndUserInfoKeyalways stores NSValue, so no need to check it.

UIKeyboardFrameEndUserInfoKey总是存储NSValue,所以不需要检查它。

回答by Murray Sagal

In Swift, not in one line...

在 Swift 中,不是在一行中......

self.keyboardDidShowObserver = NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { (notification) in
        if let userInfo = notification.userInfo, let keyboardFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
            let keyboardRect = keyboardFrameValue.CGRectValue()
            // keyboardRect.height gives the height of the keyboard
            // your additional code here...
        }
    })

回答by Leo Cavalcante

[notificationCenter addObserverForName:UIKeyboardWillChangeFrameNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification * _Nonnull note) {

    float keyboardHeight = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;

}];

回答by alex-i

I noticed an issue showing when switching between default keyboard and a custom (UIPickerView) keyboard - the custom keyboard would show a 253 height instead of 162, after switching from the default keyboard.

我注意到在默认键盘和自定义 ( UIPickerView) 键盘之间切换时出现的问题- 从默认键盘切换后,自定义键盘将显示 253 高度而不是 162。

What worked in this case was setting autocorrectionType = UITextAutocorrectionTypeNo;for the input field with the custom keyboard.

在这种情况下autocorrectionType = UITextAutocorrectionTypeNo;,使用自定义键盘设置输入字段是有效的。

The issue only occured in iOS 8 (tested on simulator only). It doesn't occur in iOS 9 (simulator or device).

该问题仅在 iOS 8 中出现(仅在模拟器上测试)。它不会发生在 iOS 9(模拟器或设备)中。