iPhone X如何处理View Controller inputAccessoryView?

LOP*_*uke 20 iphone ios inputaccessoryview iphone-x

我有一个消息传递应用程序,它具有全屏表格视图底部的文本字段的典型UI设计.我将该文本字段设置为视图控制器inputAccessoryView并调用ViewController.becomeFirstResponder()以使字段显示在屏幕底部.

我知道这是Apple推荐的实现这种UI结构的方法,它在"经典"设备上运行得很好但是当我在iPhone X模拟器上测试时,我注意到使用这种方法,文本字段不尊重新的"安全区域" .文本字段显示在主屏幕指示器下方屏幕的最底部.

我查看了HIG文档,但没有找到任何关于inputAccessoryView视图控制器的有用信息.

这很难,因为使用这种方法我实际上并没有直接控制任何约束,我只是设置inputAccessoryView并让视图控制器从那里处理UI.所以我不能仅仅把这个领域限制在新的安全区域.

有没有人在这方面找到了很好的文档,或者知道在iPhone X上运行良好的替代方法?

在此输入图像描述

小智 35

inputAccessoryView 和iPhone X上的安全区域

  • 当键盘不可见时,inputAccessoryView它固定在屏幕的最底部.没有办法解决这个问题,我认为这是预期的行为.

  • 视图的layoutMarginsGuide(iOS 9+)和safeAreaLayoutGuide(iOS 11)属性设置为inputAccessoryView尊重安全区域,即在iPhone X上:

    • 当键盘不可见时,bottomAnchor主页按钮区域的帐户
    • 当键盘显示时,bottomAnchor它位于键盘的底部inputAccessoryView,这样它就不会在键盘上方留下任何无用的空间

工作范例:

import UIKit

class ViewController: UIViewController {

    override var canBecomeFirstResponder: Bool { return true }

    var _inputAccessoryView: UIView!

    override var inputAccessoryView: UIView? {

        if _inputAccessoryView == nil {

            _inputAccessoryView = CustomView()
            _inputAccessoryView.backgroundColor = UIColor.groupTableViewBackground

            let textField = UITextField()
            textField.borderStyle = .roundedRect

            _inputAccessoryView.addSubview(textField)

            _inputAccessoryView.autoresizingMask = .flexibleHeight

            textField.translatesAutoresizingMaskIntoConstraints = false

            textField.leadingAnchor.constraint(
                equalTo: _inputAccessoryView.leadingAnchor,
                constant: 8
            ).isActive = true

            textField.trailingAnchor.constraint(
                equalTo: _inputAccessoryView.trailingAnchor,
                constant: -8
            ).isActive = true

            textField.topAnchor.constraint(
                equalTo: _inputAccessoryView.topAnchor,
                constant: 8
            ).isActive = true

            // this is the important part :

            textField.bottomAnchor.constraint(
                equalTo: _inputAccessoryView.layoutMarginsGuide.bottomAnchor,
                constant: -8
            ).isActive = true
        }

        return _inputAccessoryView
    }

    override func loadView() {

        let tableView = UITableView()
        tableView.keyboardDismissMode = .interactive

        view = tableView
    }
}

class CustomView: UIView {

    // this is needed so that the inputAccesoryView is properly sized from the auto layout constraints
    // actual value is not important

    override var intrinsicContentSize: CGSize {
        return CGSize.zero
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里查看结果

  • 好东西。对我来说,`intrinsicContentSize`是神奇的。甚至不必更改`translatesAutoresizingMask ...'属性。 (3认同)

ahb*_*bou 32

这是iPhone X上的inputAccessoryViews的一般问题.inputAccessoryView忽略其窗口的safeAreaLayoutGuides.

要修复它,您必须在视图移动到其窗口时在类中手动添加约束:

override func didMoveToWindow() {
    super.didMoveToWindow()
    if #available(iOS 11.0, *) {
        if let window = self.window {
            self.bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow(window.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0).isActive = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:self这里指的是inputAccessoryView.

我在这里详细介绍了它:http://ahbou.org/post/165762292157/iphone-x-inputaccessoryview-fix

  • 这是最好的答案,应该被接受而不是更复杂的答案. (3认同)
  • 不知何故,我得到了“无法同时满足约束条件”。错误:/您是否也有,还是我的错误?它仍然有效:D (3认同)
  • 开箱即用,应该是公认的答案。谢谢@ahbou (2认同)
  • 这个答案基本上非常好,并且是让您继续前进的最简单方法,但由于某种原因,它会在 iPhone 6 和 iPhone 6 Plus 设备上引起问题,如果您尝试在具有此内容的屏幕上呈现视图控制器inputAccessoryView,在呈现视图控制器之前屏幕会黑一会儿。UIAlertControllers、UIActivityViewControllers 和任何其他 UIViewController 子类都会发生这种情况。 (2认同)

Vla*_*lad 7

在Xib中,在设计底部找到一个正确的约束,然后将item设置为Safe Area而不是Superview

之前在此处输入图片说明

解决在此处输入图片说明

之后在此处输入图片说明