StupidBeauty
Read times:1016Posted at:Thu Jun 19 05:52:10 2014
- no title specified

苹果开发教程翻译:iOS 7 自动布局教程:第2部分,Beginning Auto Layout Tutorial in iOS 7: Part 2,第二页

上一页

妳可能正在纳闷,这些尺寸约束在哪里?在这个例子中,该视图的尺寸是由它的超类的尺寸推算出来的。在这个布局中,有两个Horizontal Spaces和两个Vertical Spaces,并且它们的长度都是固定的。妳可以在Document Outline 中看到这一点:

绿色视图的宽度是由这个公式超视图的宽度-(98 + 62)”计算出来的,高度是由这个公式超视图的高度-(65 + 199)”计算出来的。这些间距约束都是固定的,所以,这个视图一定会改变自己的尺寸。(再次说明,妳的具体值可能跟这里不一样,这取决于妳将该视图拖放到哪里去了。)

当妳旋转模拟器时,超视图的尺寸从320×568 变成 568×320。将这一对新的宽度和高度值代入到公式中,就能够计算出绿色视图的新尺寸(408×56)

当妳运行这个程序并且切换到横向模式时,就能够看到这个效果,但是,妳也可以在Interface Builder 中直接模拟这个效果。打开Assistant editor(按下Xcode的工具条中那个长得像一个老管家/外星人的按钮),然后选择跳转工具条中的Preview

点击底部的箭头按钮,以将朝向改变成横向模式。这样就会立即预览到该故事板在横向模式下的显示效果。绿色按钮的尺寸发生了改变,以满足它的HorizontalVertical Space约束

妳可以在设计用户界面时让这个预览面板保持打开状态,这样,它会自动更新显示情况。妳还可以使用它来在3.5英寸和4英寸的显示效果之间切换。

注意:妳是不是觉得奇怪,为什么该视图顶部的那个约束没有一直达到屏幕的顶部呢:

它只是延伸到状态栏底部为止。但是,在iOS 7 中,状态栏永远被绘制在视图控制器的上方——它不再是一个独立的横条了——那么,现在是怎么回事?当妳创建这个约束时,它不是吸附到屏幕的顶部,而是吸附到一条看不见的线上去了,这条线叫做 顶部布局参考线 Top Layout Guide)。

在一个普通的视图控制器中,这条参考线位于屏幕顶部以下20点的地方,至少在状态栏未被隐藏时会是如此。在一个导航式控制器中,它位于导航条下方。因为导航条在横向模式下具有不同的高度,所以,当设备发生旋转时, 顶部布局参考线 会随着导航条移动。这个特性使得妳可以轻易地按照相对于导航条的位置来放置各个视图。另外还存在一个 底部布局参考线 Bottom Layout Guide),用于标签条和工具条。

妳可能并不总是希望妳的UIView 随着设备的旋转而改变尺寸,这种情况下,妳可以使用约束来为该视 图设置一个固定的宽度和/或高度。现在让我们来试验一下。选中绿色视图,然后单击Pin按钮;在弹出的面板中,选中Width Height 前面的复选框。

单击Add 2 Constraints按钮以完成操作。此时,妳向该视图加入了两个新的约束了:一个160点的Width约束和一个284点的Height约束

因为WidthHeight约束是只与这个视图相关的,所以,在Document Outline 中,它们是位于该View 下面。通常情况下,约束所表达的是两个不同视图之间的关系——例如,这里的HorizontalVertical Space约束是位于绿色视图和它的超视图之间的——但是,妳可以将Width Height 约束看作是绿色视图与它自身之间的一个关系。

运行这个应用程序。啊,竖向模式下看起来不错。好,切换到横向模式吧。搞个鸟!不仅界面看起来跟妳想要的不一样——这个视图再次改变了尺寸——而且Xcode的调试面板中还输出了一条恶心的错误信息:

Gallery[39367:a0b] 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:0xc1a1e80 V:[UIView:0xc1a2b10(284)]>",

"<NSLayoutConstraint:0xc1a36c0 V:[_UILayoutGuide:0xc1a2d20]-(65)-[UIView:0xc1a2b10]>",

"<NSLayoutConstraint:0xc1a36f0 V:[UIView:0xc1a2b10]-(199)-[_UILayoutGuide:0xc1a3230]>",

"<_UILayoutSupportConstraint:0xc15dbd0 V:[_UILayoutGuide:0xc1a2d20(20)]>",

"<_UILayoutSupportConstraint:0xc1a1510 V:|-(0)-[_UILayoutGuide:0xc1a2d20] (Names: '|':UIView:0xc1a2930 )>",

"<_UILayoutSupportConstraint:0xc1a3720 V:[_UILayoutGuide:0xc1a3230(0)]>",

"<_UILayoutSupportConstraint:0xc1a30e0 _UILayoutGuide:0xc1a3230.bottom == UIView:0xc1a2930.bottom>",

"<NSAutoresizingMaskLayoutConstraint:0x8c6c6a0 h=--& v=--& H:[UIView:0xc1a2930(320)]>"

)

Will attempt to recover by breaking constraint

<NSLayoutConstraint:0xc1a1e80 V:[UIView:0xc1a2b10(284)]>

Break on objc_exception_throw to catch this in the debugger.

The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

. . .

记得吗?我曾经说过,必须要有足够多的约束, 自动布局 系统才能够计算出所有视图的位置和尺寸。那么,妳现在看到的这个例子里,有了过多的约束。当妳遇到“Unable to simultaneously satisfy constraints”这条错误信息时,就表示,某些约束条件互相冲突了。

现在重新审视一下这些约束:

在绿色视图上有6个约束:其中4个Spacing约束,妳已经见过(1-4);还有新加的WidthHeight约束,这是妳刚刚加上的(56)。那么,哪里起冲突了?

在竖向模式中,没有问题,因为各个约束的数值是刚好符合的。超视图的宽度是320点。如果妳把那些Horizontal SpaceWidth约束的值加起来,那么,结果也是320。按照我现在放置该视图的情况来看,具体的值就是:98 + 160 + 62 = 320。类似地,竖直方向上各个约束的值加起来之后应当是568

但是,当妳将设备旋转到横向模式时,窗口(同时也包括超视图)的宽度变成568了。那么现在数学等式变成了98 + 160 + 62 + ? = 568。在等式中,还缺少248个额外的点,而 自动布局 系统不知道从哪里去凑来这额外的点。竖直方向上也有类似的问题。

这里的冲突就在于:该视图的宽度应当固定,让其中某个边距变成可变的;或者,将边距固定,让宽度变成可变的。妳不能让两个东西都固定。所以,必需去掉其中某个约束。在以上的示例中,妳希望该视图在竖向和横向模式下都保持其宽度、高度不变,所以,应当去掉右侧的Horizontal Space约束

删除右侧Horizontal Space约束和底部的Vertical Space约束。现在,故事板应当变成这样的了:

现在,这个视图拥有了刚好足够确定它的尺寸和位置的约束了——不多也不少。运行这个应用程序,确认一下,错误消息是不是已经消失了,这个视图是不是在旋转之后还保持着相同的尺寸。

注意:虽然Interface Builder会尽一切可能来向妳发出关于无效布局的警告,但是,它也无法创造奇迹。它发现当前没有足够多的约束时,会警告妳,但是,它并不太擅长于检测出约束过多的情况。不管怎样,当有错误发生时, 自动布局 系统会输出一砣详细的错误信息。

绘制肖像

拖放一个Label 到绿色视图上去。注意看,现在参考线是出现在绿色视图的内部了,因为,它是该文本标签对象的超视图。

按照参考线的指示,将该文本标签正好放置在底部的边距处,水平方向居中。加入一个距离约束(space constraint),使得该文本标签固定在绿色视图的底部上方20 点处。最快的方式就是,使用Pin按钮,再选中底部的工型符号:

现在,加入一个约束,来让该文本标签水平居中。妳已经学过使用Editor\Align菜单来做到这个,但是,妳还可以使用浮动的 自动布局 菜单中的Align 按钮。选中这个文本标签,然后点击Align按钮以弄出那个弹出式面板:

选中Horizontal Center in Container 前面的复选框,然后点击Add 1 Constraint。故事板现在应该是这样的:

注意看,这里新加入的HorizontalVertical Space约束是列在绿色视图自己的Constraints 区域中的,而不是在主视图中。

向故事板上拖入一个新的Image View对象,使得布局变成这样:

这个图片视图与它的超视图的顶部、左侧和右侧边缘保持固定距离,而它的底部是与已有的文本标签对象保持标准的8点的距离。如果妳还是不明白该怎么设置这个,那么,按照以下步骤来。

1. 将图片视图拖入到绿色视图中,但是先不要太在意它的尺寸和位置:

2. 选中该图片视图,按下Pin按钮,然后选择以下选项:

顶部、左侧和右侧的工型符号的值都被设置成20点,底部的那个被设置成8点。注意:对于Update Frames 这个选项,妳应当选择Items of New Constraints。如果妳不选择这个,让它保持为None,则,故事板会是这样的:

妳所设置的约束,与该图片当前的位置及尺寸不符合。但是,如果妳选择了Items of New Constraints,那么,Interface Builder会在添加约束时自动调整该视图的几何属性,使得一切东西都看起来狠帅:

当然,如果妳真的造成了“放偏了位置”的情况,那么,妳还是可以使用Resolve Auto Layout Issues 按钮来修复它的:

下一页

未知美人

未知美人

未知美人

Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands