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

时间:2014-09-28 18:05:53

标签: ios cocoa-touch 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);
}

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

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

Constrained Height

这应该会导致标签在指定高度填充容器而没有约束冲突。相反,我遇到了约束冲突:

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.

它打破约束的方式,它实际上看起来像我想要它: Constrained Height View

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

不限制高度

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

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

这导致了一个扩展,它占用了通知中心的整个高度,而且我的正确大小的视图垂直居中:

i.imgur.com/kKXlocu.png

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

给予什么?

我知道我可以使用preferredContentSize,但是为什么Apple会说可以使用自动布局限制来设置它?我做错了什么?

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

3 个答案:

答案 0 :(得分:36)

经过一些实验,绊倒&#34; what is NSLayoutConstraint "UIView-Encapsulated-Layout-Height" and how should I go about forcing it to recalculate cleanly&#34;我确定你可以使用&#34; Height&#34;来解决这个问题。 &安培; &#34;平等高度&#34;或者&#34;高度&#34;顶部和底部&#34;垂直空间&#34; (按照Guilherme Sprint的建议),然后降低&#34;优先级&#34;高度约束为999.

Height Constraint with Reduced Priority

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

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

答案 1 :(得分:5)

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

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

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

顺便说一下,你应该将这些约束挂钩到布局边距,正如Apple推荐的那样,特别是今日扩展。

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

Xcode Today Extension Constraints

只是解释一下,高度约束将为子视图设置一个常量,并且顶部和底部约束将&#34;粘合&#34;子视图边缘的超视图。

Today Extension running

答案 2 :(得分:0)

标签的高度使得无法同时满足这些约束条件:

  • 标签最小高度
  • Superview的顶级空间
  • 超级视图的底部空间

您可以通过删除Bottom Space to Superview约束来解决它,autolayout系统将为底部空间分配剩余空间。