在某些情况下尝试自动调整大小时,键盘扩展会在 iOS 10 中失去高度
Keyboard extension loses height in iOS 10 when trying to size automatically in some cases
您可以在此处下载演示以下问题的示例项目:
https://github.com/DimaVartanian/keyboard-extension-height-bug
在创建键盘扩展时并没有为其组件指定具体高度,而是将它们锚定到 view/inputView 以便理论上系统将根据环境和方向确定它们的高度,在某些情况下高度变为 0 并且键盘被压碎(具有具体高度的任何东西除外,例如自定大小的标签或按钮)。
这似乎只发生在 iOS 10 上。 在 iOS 9 上,子视图正确调整大小以适应默认的自动键盘高度。
这可以体现多种场景,本项目演示了一个基本场景。它以带有默认 "next keyboard" 按钮的基本键盘扩展模板和它附带的 2 个大小限制开始:
self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
接下来,我们创建一个单独的其他视图,我们想要填充父视图的 space 而无需为其本身定义具体大小:
let anotherView = UIView()
anotherView.backgroundColor = UIColor.red
anotherView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(anotherView)
anotherView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
anotherView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
anotherView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
现在,假设我们只想将这个新视图锚定到键盘超级视图的底部。我们会做类似的事情:
anotherView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
结果如下所示:
iOS 9
iOS 10
这个布局正是我们所期望的。现在,让我们将新视图锚定到下一个键盘按钮的顶部。我们摆脱刚刚添加的约束并将其替换为
anotherView.bottomAnchor.constraint(equalTo: self.nextKeyboardButton.topAnchor).isActive = true
从逻辑上讲,得到的高度应该是一样的(由系统决定)
现在的结果是这样的:
iOS 9
iOS 10
在 iOS 9 上,它的行为符合预期,但在 iOS 10 上,灵活高度视图的大小被调整为 0,剩下的就是固定高度按钮。
没有关于约束冲突的消息。我试图弄清楚是什么原因造成的,以及为什么它只会在 iOS 10.
上发生
我也遇到了同样的问题。这是因为自动布局约束。只需删除所有约束。并设置自动调整大小。
我通过设置新的高度约束解决了这个问题。
Apple 已回复我的 DTS 请求并告诉我提交错误报告,所以这实际上是一个 iOS 10 错误。我已经提交了一个雷达 (#28532959),如果我得到回复,我会更新这个答案。如果其他人想出了一个具体的解决方案,让我仍然可以使用自动布局来实现自动高度,答案仍然被接受。
这是我的解决方法。设备旋转时有点迟钝,但在 Apple 修复此错误之前它会完成工作。我最初以为它与 inputView.allowSelfSizing
有关,但那个变量似乎没有改变任何东西。
首先声明heightConstraint
:
var heightConstraint: NSLayoutConstraint!
在 viewDidLoad
中,添加您的自定义视图:
let nibName: String! = UIDevice.isPhone ? "KeyboardViewiPhone" : "KeyboardViewiPad"
customView = Bundle.main.loadNibNamed(nibName, owner: self, options: nil)?.first as! UIView
customView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(customView)
像往常一样添加宽度约束:
let widthConstraint = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: customView, attribute: .width, multiplier: 1.0, constant: 0.0)
为高度添加一个常量约束:
heightConstraint = NSLayoutConstraint(item: customView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.frame.height)
view.addConstraints([widthConstraint, heightConstraint])
现在修复了:
override func viewDidLayoutSubviews() {
heightConstraint.constant = view.bounds.height
}
由于每次 view.bounds
更改时都会调用 viewDidLayoutSubviews
,因此它将正确处理方向更改。
我在 Xcode 8.2 中的自定义键盘扩展也遇到了同样的问题。这是由 auto resizing
引起的。就我而言,我通过以下方式解决了这个问题。
最初,我的自定义键盘有 3 个视图。
在此,我固定了第一个和最后一个视图的尾随、前导、顶部和高度。并像图像中那样放置中间视图。
之后 select 中间视图并在故事板中打开 show the size inspector
。在 size inspector,
中,您会找到一个选项 auto resizing
。在那select那个视图的约束指标。
select在设备中 运行 您的项目后,它将正常工作而不会丢失任何视图。
注意:- 它适用于纵向和横向模式。主要是你不必为中间视图提供约束。
恕我直言,最好的解决方案是使用 "Proportional Height"。例如,就我而言,我最终以 2 个视图结束。顶部的超级视图高度为 0.8,底部为 0.2。这不是完美的解决方案,但您仍然可以从自动布局中受益。
您可以在此处下载演示以下问题的示例项目: https://github.com/DimaVartanian/keyboard-extension-height-bug
在创建键盘扩展时并没有为其组件指定具体高度,而是将它们锚定到 view/inputView 以便理论上系统将根据环境和方向确定它们的高度,在某些情况下高度变为 0 并且键盘被压碎(具有具体高度的任何东西除外,例如自定大小的标签或按钮)。
这似乎只发生在 iOS 10 上。 在 iOS 9 上,子视图正确调整大小以适应默认的自动键盘高度。
这可以体现多种场景,本项目演示了一个基本场景。它以带有默认 "next keyboard" 按钮的基本键盘扩展模板和它附带的 2 个大小限制开始:
self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
接下来,我们创建一个单独的其他视图,我们想要填充父视图的 space 而无需为其本身定义具体大小:
let anotherView = UIView()
anotherView.backgroundColor = UIColor.red
anotherView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(anotherView)
anotherView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
anotherView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
anotherView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
现在,假设我们只想将这个新视图锚定到键盘超级视图的底部。我们会做类似的事情:
anotherView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
结果如下所示:
iOS 9
iOS 10
这个布局正是我们所期望的。现在,让我们将新视图锚定到下一个键盘按钮的顶部。我们摆脱刚刚添加的约束并将其替换为
anotherView.bottomAnchor.constraint(equalTo: self.nextKeyboardButton.topAnchor).isActive = true
从逻辑上讲,得到的高度应该是一样的(由系统决定)
现在的结果是这样的:
iOS 9
iOS 10
在 iOS 9 上,它的行为符合预期,但在 iOS 10 上,灵活高度视图的大小被调整为 0,剩下的就是固定高度按钮。
没有关于约束冲突的消息。我试图弄清楚是什么原因造成的,以及为什么它只会在 iOS 10.
上发生我也遇到了同样的问题。这是因为自动布局约束。只需删除所有约束。并设置自动调整大小。
我通过设置新的高度约束解决了这个问题。
Apple 已回复我的 DTS 请求并告诉我提交错误报告,所以这实际上是一个 iOS 10 错误。我已经提交了一个雷达 (#28532959),如果我得到回复,我会更新这个答案。如果其他人想出了一个具体的解决方案,让我仍然可以使用自动布局来实现自动高度,答案仍然被接受。
这是我的解决方法。设备旋转时有点迟钝,但在 Apple 修复此错误之前它会完成工作。我最初以为它与 inputView.allowSelfSizing
有关,但那个变量似乎没有改变任何东西。
首先声明heightConstraint
:
var heightConstraint: NSLayoutConstraint!
在 viewDidLoad
中,添加您的自定义视图:
let nibName: String! = UIDevice.isPhone ? "KeyboardViewiPhone" : "KeyboardViewiPad"
customView = Bundle.main.loadNibNamed(nibName, owner: self, options: nil)?.first as! UIView
customView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(customView)
像往常一样添加宽度约束:
let widthConstraint = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: customView, attribute: .width, multiplier: 1.0, constant: 0.0)
为高度添加一个常量约束:
heightConstraint = NSLayoutConstraint(item: customView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.frame.height)
view.addConstraints([widthConstraint, heightConstraint])
现在修复了:
override func viewDidLayoutSubviews() {
heightConstraint.constant = view.bounds.height
}
由于每次 view.bounds
更改时都会调用 viewDidLayoutSubviews
,因此它将正确处理方向更改。
我在 Xcode 8.2 中的自定义键盘扩展也遇到了同样的问题。这是由 auto resizing
引起的。就我而言,我通过以下方式解决了这个问题。
最初,我的自定义键盘有 3 个视图。
在此,我固定了第一个和最后一个视图的尾随、前导、顶部和高度。并像图像中那样放置中间视图。
之后 select 中间视图并在故事板中打开 show the size inspector
。在 size inspector,
中,您会找到一个选项 auto resizing
。在那select那个视图的约束指标。
select在设备中 运行 您的项目后,它将正常工作而不会丢失任何视图。
注意:- 它适用于纵向和横向模式。主要是你不必为中间视图提供约束。
恕我直言,最好的解决方案是使用 "Proportional Height"。例如,就我而言,我最终以 2 个视图结束。顶部的超级视图高度为 0.8,底部为 0.2。这不是完美的解决方案,但您仍然可以从自动布局中受益。