【问题标题】:iPhoneX and iPhone 8 keyboard height are differentiPhone X 和 iPhone 8 键盘高度不同
【发布时间】:2018-03-07 07:48:17
【问题描述】:

我使用下面的代码来获取键盘高度。然后使用这个高度来计算UIView 的框架,以确保这个UIView 正好在键盘的顶部。

但在 iPhoneX 模拟器中,输出是 333,而 iPhone 8 模拟器是 258

问题:如果使用rect.height 作为iPhone 8 模拟器的键盘高度,那么布局是正确的。对于 iPhone X,UIView 和键盘之间存在间隙。这意味着333 高于 iPhone X 中的实际键盘高度。

身高不一样的原因是什么?以及如何获得正确的键盘高度?

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)


@objc func keyboardWillShow(_ notification: NSNotification) {
        if let rect = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
           print(rect.height)
        } 
    }

像这张图片一样,绿色边框应该是多余的部分。实际上,我需要键盘顶部的红色部分,没有绿色的矩形间隙。

编辑

好的,在@Craig 的帮助下,我发现这个方法只被 iPhone X 调用。所以我在这里更新框架。只需在此处粘贴代码即可。

安全区底部高度为 22.0 似乎不正确。

override func viewSafeAreaInsetsDidChange() {
    if #available(iOS 11.0, *) {
        super.viewSafeAreaInsetsDidChange()
        view.safeAreaInsets.bottom // This value is the bottom safe area place value.
    }
}

EDIT2 通常view.safeAreaInsets.bottom 应该是 34.0,但如果你使用容器视图,这个值可能会有所不同,就像我的 22.0。

【问题讨论】:

  • 您的问题究竟是什么?您在问题中要求基于意见的推测。
  • 您总是可以使用rect.height 来计算剩余的?
  • @holex 我编辑了我的问题。我的问题是我无法通过通知中的rect.height 获得正确的键盘高度。
  • @zcui93 rect.height 通常应该是键盘高度。
  • @zcui93 你说得对,我认为 iPhone X 的矩形高度不再是键盘高度。应该加上底部。

标签: ios iphone-x


【解决方案1】:

虽然Craig's answer 是正确的,但您可能不想将视图固定到 view.bottombottomLayoutGuide 而不是 安全区域底部 em>(特别是如果您的键盘并非始终打开,并且您不希望视图覆盖 Home Indicator 区域)。

以下是针对这些情况的修复方法。它从键盘高度中减去安全区域底部插图的高度:

var keyboardHeight = ... // Get the keyboard height from keyboard notification

if #available(iOS 11.0, *) {
    let bottomInset = view.safeAreaInsets.bottom
    keyboardHeight -= bottomInset
}

【讨论】:

    【解决方案2】:

    iPhone X 和 iPhone 8 的键盘高度应该是正确的。我只能猜测您的代码中可能存在用于定位“红色部分”的问题,并且您的假设是键盘高度不正确,而问题实际上出在视图的 location 中。现在 - 位置问题的原因?我的第二个猜测是红色部分固定在底部安全区域布局指南上,在 iPhone 8 上是 0,但在 iPhone X 上是插入 34 点。

    查看此图像以说明键盘高度的差异,并且可以使用键盘高度从NSNotification 中报告的keyboardWillShow 方法的键盘高度在键盘上方绘制一个矩形:

    如果您想分享定位红色视图的代码/约束,我应该可以向您展示问题。

    --编辑:对于任何有兴趣了解我如何提取绘制的红色矩形的人,我会在一篇博文here 中进行介绍。

    【讨论】:

    • 是的,我认为你是对的。 “插图是 34 pt”,我在 iPhone 8 和 iPhone X 上都试过 view.safeAreaInset 似乎都是(0,0,0,0),如何获得这个值?
    • 如果您在viewDidLoad 中尝试过,似乎此时尚未设置此值。您可以覆盖 viewSafeAreaInsetsDidChange 以查看此值:override func viewSafeAreaInsetsDidChange() { print(view.safeAreaInsets) }
    【解决方案3】:

    到目前为止,这适用于所有设备和 iOS 版本

    - (void)keyboardWillShown:(NSNotification*)aNotification
    {
            NSDictionary* info = [aNotification userInfo];
            CGFloat kbHeight = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
            CGFloat safeAreaBottomInset = 0;
            if (@available(iOS 11.0, *)) {
                safeAreaBottomInset = self.view.safeAreaInsets.bottom;
            }
            self.containerViewBottomConstraint.constant += (kbHeight - safeAreaBottomInset); //In my case I use a constraint to adapt the UI when the keyboard is presented
            [self.view layoutIfNeeded];
    }
    

    【讨论】:

    • 只需固定到 Superview.Bottom 约束。不安全的区域。
    【解决方案4】:

    我也遇到过这个问题。我所做的,只是检查了 iPhone 7 和 iPhone X 上不同的键盘。我只是添加了一些带有键盘高度的默认边距。现在它在每台设备上都可以正常工作。

    【讨论】:

    • 添加魔术固定数字永远不是一个可行的解决方案。
    【解决方案5】:

    覆盖 func viewDidLoad() { super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    //Here keyboard is without any toolbar and suggestions boxes
    @objc func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            let keyboardHeight = ((keyboardSize.height) > 240) ? 220 :  (keyboardSize.height - 47)
            self.view.layoutIfNeeded()
        }
    
    }
    

    【讨论】:

    • 使用这样的幻数并不漂亮。当 Apple 决定改变 home bar 的高度时会发生什么?他们以前也这样做过……
    【解决方案6】:

    如果您的视图嵌入为子视图(如 TabBar 或 PagerViewController)并且您无权访问父视图(例如,如果您是框架),则可能会变得棘手。

    这也可以通过当前视图高度与窗口高度和当前视图的Y位置的差异来计算:

    斯威夫特:

    func calculateHeightOffsetFromContainer() -> CGFloat {
        let convertedYInParent = self.view.convert(self.view.frame, to: nil).origin.y
        let offsetInViewHeights = UIScreen.main.bounds.height - self.view.frame.height
        return offsetInViewHeights - convertedYInParent;
    }
    

    用法:

    let keyboardYPosition = keyboardFrame.height - offsetFromConteiner
    

    目标 C:

    - (CGFloat)calculateHeightOffsetFromContainer {
        CGFloat convertedYInParent = [self.view convertRect: self.view.frame toView: nil].origin.y;
        CGFloat offsetInViewHeights = [UIScreen mainScreen].bounds.size.height - self.view.frame.size.height;
        return offsetInViewHeights - convertedYInParent;
    }
    

    用法:

    CGFloat keyboardYPosition = keyboardFrame.size.height - offsetFromConteiner;
    

    【讨论】:

      猜你喜欢
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 2010-11-05
      • 2011-06-09
      • 2012-10-09
      • 1970-01-01
      相关资源
      最近更新 更多