问题
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.
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]>
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.)
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)?
What I'm basically trying to achieve with the bounty...
... 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?)
Closely related question that's part of the problem and might give a hint:
Inconsistent Today Widget behavior breaks subview's height constraints
回答1:
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.
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
.
回答2:
The way that I've found helpful is to constrain a view on the top and the bottom, center it horizontally, and constrain the width. This has given me good results on the today widgets that I've worked on.
来源:https://stackoverflow.com/questions/37009679/layout-constraint-conflicts-in-default-today-widget