43

Apple 文档建议使用自动布局设置 Today Extensions 的高度。

如果小部件有额外的内容要显示,您可以依靠自动布局约束来适当地调整小部件的高度。如果不使用 Auto Layout,可以使用 UIViewController 属性 preferredContentSize 来指定小部件的新高度。

但是,我看到的每个示例和教程最终都使用preferredContentSize.

我所有通过自动布局设置高度的尝试都会导致约束被破坏的警告。

通过自动布局设置高度

我从一个新的 xcode 模板和一个新的 Today 扩展模板开始。我添加的唯一内容TodayViewController.m是:

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
    return UIEdgeInsetsMake(0, 0, 0, 0);
}

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

我限制了标签高度,将标签在容器中居中,并限制容器高度与标签高度相同:

约束高度

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

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.

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

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

不限制高度

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

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

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

i.imgur.com/kKXlocu.png

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

是什么赋予了?

我知道我可以只使用preferredContentSize,但是为什么 Apple 会说它可以使用自动布局约束来设置呢?我究竟做错了什么?

我给出的例子显然是人为的。我正在设置视图的高度,那为什么不直接设置容器的高度,对吧?在实际项目中,部分要点是仅使用自动布局根据宽度设置小部件的高度。

4

3 回答 3

36

经过一些试验,并偶然发现“什么是 NSLayoutConstraint “UIView-Encapsulated-Layout-Height”,我应该如何强制它重新计算干净“我确定您可以使用“高度”和“等高”来规避这个问题或“高度”和顶部和底部“垂直空间”(由Guilherme Sprint建议),然后将高度约束的“优先级”降低到 999。

优先级降低的高度约束

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

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

于 2014-10-08T09:44:52.030 回答
5

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

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

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

顺便说一句,您应该将此约束与布局边距挂钩,正如 Apple 建议的视图,特别是 Today Extensions。

第 5 个约束将是子视图的高度。这个约束,连同顶部和底部的空间,将定义您在 Today Tab 中的部分的确切大小。

Xcode Today 扩展约束

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

今天扩展运行

于 2014-10-02T19:04:35.017 回答
0

标签的高度使得不可能同时满足这些约束:

  • 标签最小高度
  • 顶部空间到 Superview
  • Superview 的底部空间

您可以通过删除Bottom Space to Superview约束来解决它,并且自动布局系统会将剩余空间分配给bottom space。

于 2015-04-28T10:24:09.233 回答