简体   繁体   English

在某些情况下尝试自动调整大小时,iOS 10中的键盘扩展名会失去高度

[英]Keyboard extension loses height in iOS 10 when trying to size automatically in some cases

You can download a sample project demonstrating the issue below here: https://github.com/DimaVartanian/keyboard-extension-height-bug 您可以在此处下载演示以下问题的示例项目: https : //github.com/DimaVartanian/keyboard-extension-height-bug

When creating a keyboard extension and not specifying a concrete height for its components but instead anchoring them to the view/inputView so that in theory the system will determine their height based on environment and orientation, in some situations that height instead turns into 0 and the keyboard is crushed (with the exception of anything that has a concrete height such as a self sized label or button). 创建键盘扩展名时,未为其组件指定具体的高度,而是将其锚定到view / inputView上,以便理论上系统将根据环境和方向确定其高度,在某些情况下,高度变为0,并且键盘被压碎(具有特定高度的任何东西,例如自定尺寸的标签或按钮除外)。

This only seems to occur on iOS 10. On iOS 9, the child views resized correctly to fit the default automatic keyboard height. 这似乎仅发生在iOS 10上。在iOS 9上,子视图的大小已正确调整以适合默认的自动键盘高度。

There are several scenarios this can manifest and this project demonstrates a basic one. 这可以体现几种情况,并且该项目演示了一个基本的情况。 It starts with the basic keyboard extension template with the default "next keyboard" button and the 2 size constraints it comes with: 它从带有默认“下一个键盘”按钮的基本键盘扩展模板开始,并附带两个尺寸限制:

self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

Next, we create a single other view that we want to fill the space of the superview without defining a concrete size for itself: 接下来,我们创建一个单独的其他视图,以填充超级视图的空间,而无需为其自身定义具体大小:

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

Now, let's say we just want to anchor this new view to the bottom of our keyboard superview. 现在,假设我们只想将此新视图锚定在键盘超级视图的底部。 We would just do something like: 我们只会做类似的事情:

anotherView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

The result looks like this: 结果看起来像这样:

iOS 9 iOS 9 在此处输入图片说明

iOS 10 iOS 10 在此处输入图片说明

This layout is exactly what we expect. 这种布局正是我们所期望的。 Now instead, let's anchor the new view to the top of our next keyboard button. 现在,让我们将新视图锚定到下一个键盘按钮的顶部。 We get rid of the constraint we just added and replace it with 我们摆脱了刚刚添加的约束,并将其替换为

anotherView.bottomAnchor.constraint(equalTo: self.nextKeyboardButton.topAnchor).isActive = true

Logically, the resulting height should be the same (determined by the system) 从逻辑上讲,结果高度应相同(由系统确定)

The result is now this: 现在的结果是这样的:

iOS 9 iOS 9 在此处输入图片说明

iOS 10 iOS 10 在此处输入图片说明

On iOS 9 it behaves as expected but on iOS 10, the flexible height view is resized down to 0 and all that is left is the fixed height button. 在iOS 9上,它的行为符合预期,但在iOS 10上,“灵活高度”视图的大小缩小为0,剩下的只是固定高度按钮。

There are no messages about conflicting constraints. 没有有关约束冲突的消息。 I'm trying to figure out what could be causing this and why it would only be happening on iOS 10. 我试图弄清楚是什么原因以及为什么它只会在iOS 10上发生。

Apple has responded to my DTS ticket and told me to file a bug report, so this is actually an iOS 10 bug. 苹果已经回应了我的DTS票证,并告诉我提交错误报告,因此,这实际上是iOS 10的错误。 I have filed a radar (#28532959) and will update this answer if I ever get a response. 我已提交雷达(#28532959),如果得到回复将更新此答案。 If someone else comes up with a concrete solution that allows me to still use autolayout to achieve an automatic height, answers are still accepted. 如果其他人提出了一个具体的解决方案,使我仍然可以使用自动布局来实现自动高度设置,那么答案仍然可以接受。

Here's my workaround. 这是我的解决方法。 It is a little laggy when the device rotates, but it will do the job until Apple fixes this bug. 当设备旋转时,它有些迟钝,但是它将完成工作,直到Apple修复了该错误。 I first thought it had something to do with inputView.allowSelfSizing , but that variable didn't seem to change anything. 我首先以为它与inputView.allowSelfSizing ,但是该变量似乎没有任何改变。

First, declare heightConstraint : 首先,声明heightConstraint

var heightConstraint: NSLayoutConstraint!

In viewDidLoad , Add your custom view: 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)

Add a constraint for the width as you would do normally: 像通常那样添加宽度约束:

let widthConstraint = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: customView, attribute: .width, multiplier: 1.0, constant: 0.0)

Add a constant constraint for the height: 为高度添加一个常量约束:

heightConstraint = NSLayoutConstraint(item: customView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.frame.height)
view.addConstraints([widthConstraint, heightConstraint])

Now comes the fix: 现在修复:

override func viewDidLayoutSubviews() {
    heightConstraint.constant = view.bounds.height
}

As viewDidLayoutSubviews is called every time view.bounds changes, it will handle orientation changes correctly. 每次view.bounds更改时都会调用viewDidLayoutSubviews ,它将正确处理方向更改。

I also faced the same issue. 我也面临同样的问题。 this is because of the Autolayout Constraints. 这是由于自动版式约束。 Just remove all constraints. 只需删除所有约束即可。 and set auto resizing. 并设置自动调整大小。 在此处输入图片说明

I got it solved by setting a new constrain for the height. 我通过为高度设置新的约束来解决它。

在此处输入图片说明

I have also faced the same problem for the custom keyboard extension in Xcode 8.2. 对于Xcode 8.2中的自定义键盘扩展,我也遇到了同样的问题。 This is caused by the auto resizing . 这是由auto resizing引起的。 In my case, I solved this in the below manner. 就我而言,我通过以下方式解决了这个问题。

Initially, my custom keyboard have 3 views. 最初,我的自定义键盘有3个视图。 In this, I was fixed the trailing, leading, top and height for the first and last view. 在此,我固定了第一个和最后一个视图的结尾,开头,顶部和高度。 And place the middle view like in the image. 并将中间视图放置在图像中。 在此处输入图片说明

after that select the middle view and open the show the size inspector in the storyboard. 之后,选择中间视图并在情节提要中打开show the size inspector In the size inspector, you will find an option auto resizing . size inspector,您会发现一个auto resizing的选项。 In that select the constraint indicators for that view. 在那选择该视图的约束指示符。

在此处输入图片说明

After selecting that you run your project in a device and it will work correctly without missing any view. 选择要在设备中运行的项目后,它将正常运行而不会丢失任何视图。

Note: - It will work for both portrait and landscape modes. 注意:-它适用于纵向和横向模式。 And mainly you don't have to give constraints for the middle view. 而且,您基本上不必为中间视图提供约束。

IMHO, best working solution is using "Proportional Height". 恕我直言,最好的解决方案是使用“比例高度”。 For example, in my case, I finally ended with 2 views. 例如,就我而言,我最终以2个视图结束。 Top one got 0.8 of height of superview, bottom - 0.2. 排名前1位的超级用户的观看高度为0.8,底部为0.2。 It's not perfect solution, but you can still benefits from autolayout. 这不是完美的解决方案,但是您仍然可以从自动布局中受益。

成比例的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM