我在刚刚为我的应用程序创建的 Today Widget 中观察到了一个关于自动布局的非常奇怪的行为.试图找到问题的根源,我最终创建了一个普通的 新 Xcode 项目(单视图应用程序)并添加了一个 Today Extension 作为新目标 - 甚至没有触及它.
I have observed a very strange behavior regarding Autolayout in the Today Widget I just created for my app. Trying to get to the root of the problem I ended up creating a plain new Xcode project (single view app) and added a Today Extension as a new target - without even touching it.
当我在我的设备 (iPhone 6s) 上启动 Today Extension 时,首先发生的事情是控制台中引发了布局约束冲突:
When I launch the Today Extension on my device (iPhone 6s) the first thing that happens is that layout constraint conflicts are thrown in the console:
2016-05-03 18:17:22.216 TodayExtension[10183:4611907] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<_UILayoutSupportConstraint:0x15c665320 V:[_UILayoutGuide:0x15c6657b0(0)]>",
"<_UILayoutSupportConstraint:0x15c663890 V:|-(0)-[_UILayoutGuide:0x15c6657b0] (Names: '|':UIView:0x15c6642a0 )>",
"<_UILayoutSupportConstraint:0x15c666010 V:[_UILayoutGuide:0x15c666380(0)]>",
"<_UILayoutSupportConstraint:0x15c666ed0 _UILayoutGuide:0x15c666380.bottom == UIView:0x15c6642a0.bottom>",
"<NSLayoutConstraint:0x15c666b80 V:[_UILayoutGuide:0x15c6657b0]-(NSSpace(8))-[UILabel:0x15c6617c0'Hello World']>",
"<NSLayoutConstraint:0x15c666bd0 V:[UILabel:0x15c6617c0'Hello World']-(NSSpace(8))-[_UILayoutGuide:0x15c666380]>",
"<NSLayoutConstraint:0x15c552820 'UIView-Encapsulated-Layout-Height' V:[UIView:0x15c6642a0(0)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x15c666bd0 V:[UILabel:0x15c6617c0'Hello World']-(NSSpace(8))-[_UILayoutGuide:0x15c666380]>
您会注意到列表中的最后一个约束是 UIView-Encapsulated-Layout-Height
,它强制视图的高度为 0.我检查并发现引用的视图是小部件的根视图本身.因此,出于某种我无法理解的原因,系统在内部创建了一个 0 像素高度约束,该约束与 Interface Builder 中的视图设置冲突.(当您在 Xcode 中创建一个全新的 Today 扩展时,您将看到,除了固定在小部件根视图的每一侧的 UILabel 之外,什么都没有.)
You'll notice that the last one of the constraints in the list is a UIView-Encapsulated-Layout-Height
which forces a height of 0 on the view. I checked and figured that the referenced view is the widget's root view itself. So for some reason that's beyond my comprehension the system internally creates a 0 pixel-height constraint that conflicts with the setup of the view in Interface Builder. (As you will see when you create a fresh today extension in Xcode there's nothing there but a a UILabel that's pinned to each side of the widget's root view.)
通常我会声称这是一个巨大的 iOS 错误,但由于这是 Apple 用于创建 Today Widgets 的 默认 模板,我简直不敢相信它已经坏了.知道是什么导致了这种冲突行为以及如何解决它(正确)?
Normally I would claim that this is a huge iOS bug but as this is Apple's default template for creating Today Widgets I just cannot believe it's broken. Any idea what's causing this conflicting behavior and how to fix it (properly)?
... 是要弄清楚是否有一种可靠的方式可以在 Today Widget 中使用自动布局而不引入几种变通方法和肮脏的黑客攻击strong>",您不会在普通应用程序中使用.(如果您最终添加了大量创建固定帧的约束并且不让内容动态增长,那并不是 Autolayout 的真正想法,是吗?)
... is to figure out if there is a reliable way to use Autolayout in a Today Widget without introducing several workarounds and "dirty hacks" that you wouldn't use inside a normal app. (If you end up adding plenty of constraints that create fixed frames and don't let the content grow dynamically that's not really the idea of Autolayout, is it?)
密切相关的问题是问题的一部分,可能会给出提示:
Inconsistent Today Widget 行为打破了子视图的高度限制
Closely related question that's part of the problem and might give a hint:
Inconsistent Today Widget behavior breaks subview's height constraints
在 Apple 的一些库存 UIView
子类中,它们的实例化大小为零.您需要配置您的 NSLayoutConstraint
以便它们可以正确响应此初始大小.过去,我将顶部或底部约束设为不等式,以便其余约束可以正确调整自身大小而不会破坏布局.
In some of Apple's stock UIView
subclasses, they are instantiated with a size of zero. You need to configure your NSLayoutConstraint
s so that they can properly react to this initial size. In the past, I've made top or bottom constraints an inequality so that the rest of the constraints may size themselves correctly and not break the layout.
例如:设置底部约束 (<NSLayoutConstraint:0x15c666bd0 V:[UILabel:0x15c6617c0'Hello World']-(NSSpace(8))-[_UILayoutGuide:0x15c666380]>
)LessThanOrEqualTo
,constant
值为 8.0
.
Ex: Make your bottom constraint (<NSLayoutConstraint:0x15c666bd0 V:[UILabel:0x15c6617c0'Hello World']-(NSSpace(8))-[_UILayoutGuide:0x15c666380]>
) a LessThanOrEqualTo
with a constant
value of 8.0
.
这篇关于默认今日小部件中的布局约束冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!