仅使用自动布局的iOS8今日扩展的高度给出了破坏的约束

Rya*_* C. 43 cocoa-touch ios ios8 ios8-extension ios8-today-widget

Apple文档建议使用autolayout设置Today Extensions的高度.

如果窗口小部件具有要显示的其他内容,则可以依赖"自动布局"约束来适当调整窗口小部件的高度.如果不使用自动布局,则可以使用UIViewController属性preferredContentSize指定窗口小部件的新高度.

但是,我见过的每个示例和教程最终都会使用preferredContentSize.

我通过autolayout设置高度的所有尝试都会导致违反约束的警告.

通过Autolayout设置高度

我开始使用新的xcode模板和一个全新的扩展模板.我添加的唯一内容TodayViewController.m是:

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
    return UIEdgeInsetsMake(0, 0, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)

注意:如果我只使用默认边距,我仍会遇到此问题.

我约束标签高度,将标签置于容器中心,并将容器高度限制为与标签高度相同:

约束高度

这应该导致一个标签在指定的高度填充容器,没有约束冲突.相反,我得到一个约束冲突:

2014-09-28 10:27:39.254 TodayExtension[61090:2672196] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7f8b8b62c670 V:[UILabel:0x7f8b8b62d9b0'Hello World'(124)]>",
    "<NSLayoutConstraint:0x7f8b8b583020 UIView:0x7f8b8b62d6e0.height == UILabel:0x7f8b8b62d9b0'Hello World'.height>",
    "<NSLayoutConstraint:0x7f8b8b5888a0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7f8b8b62d6e0(667)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7f8b8b62c670 V:[UILabel:0x7f8b8b62d9b0'Hello World'(124)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Run Code Online (Sandbox Code Playgroud)

它打破约束的方式,它实际上看起来像我想要它: 约束高度视图

但是,在其他项目中,它决定打破其他约束并且看起来不正确.另外,旁注:如果我尝试更改高度约束的优先级,它会崩溃Xcode.这很有趣.

不限制高度

我曾经希望,因为约束高度不起作用,也许如果我没有将容器高度约束到子视图,那么也许它会找出容纳子视图并正确设置自己所需的高度.

我将子视图集中在一起并限制其高度:i.imgur.com/PwLmhj9.png

这只是导致扩展使用通知中心的整个高度,并且我的正确大小的视图垂直居中:

i.imgur.com/kKXlocu.png

如果我不居中,而是将垂直空间固定到顶部布局指南,我会得到相同的东西,除了子视图固定在顶部(但容器仍然很大).

是什么赋予了?

我知道我可以使用preferredContentSize,但是为什么Apple会说它可以使用Auto Layout约束来设置?我究竟做错了什么?

我给出的例子显然是做作的.我正在设置视图的高度,所以为什么不设置容器的高度,对吧?实际项目中的部分要点是仅使用autolayout基于宽度设置窗口小部件的高度.

Rya*_* C. 36

经过一些实验,并且遇到了" 什么是NSLayoutConstraint"UIView-Encapsulated-Layout-Height"以及如何强制它重新计算干净 "我确定你可以使用"Height"和"Equal Heights"来规避这个问题或"高度"和顶部和底部"垂直空间"(由Guilherme Sprint建议),然后将高度约束的"优先级"降低到999.

优先级降低的高度约束

这不是我希望的答案,它确实通过子视图的自动布局指定容器的高度,并避免任何有关损坏约束的警告.

我完全不科学的猜测/假设/结论是iOS正确地查看布局约束以确定容器视图的高度.然后,它会添加一个与刚刚计算的高度相同的新约束,但现在这会超出约束高度.降低原始开发人员指定的高度约束的优先级意味着系统生成的约束胜出并且没有生成警告(希望从实际知道的人那里听到更多关于此的信息).


Gui*_*ura 5

您应该总共定义5个约束,以使Today Extension成为您真正想要的大小.

4个约束将定义与superview的关系:

  • 顶级空间
  • 底部空间
  • 领先的空间
  • 尾随空间

顺便说一句,您应该将这些约束挂钩到布局边距,如Apple建议的那样,特别是Today Extensions.

第5个约束将是子视图的高度.此约束以及顶部和底部空间将定义"今日"选项卡中部分的确切大小.

Xcode Today扩展约束

只是解释一下,高度约束将为子视图设置一个常量,顶部和底部约束将"超级视图""粘合"到子视图边缘.

今天延伸运行

  • 我有同样的问题.我试过这个解决方案,但它仍然没有用.我第一次运行它看起来是正确的.但是,如果我关闭通知中心并再次重新打开它,子视图就会放错地方.我还可以在日志中看到Xcode抱怨冲突的约束.我现在就放弃并使用preferredContentSize寻求解决方案. (2认同)