StupidBeauty
Read times:996Posted at:Sat Jun 14 21:49:06 2014
- no title specified

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

原文: http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1

妳是否曾有这样的经历,当妳想让妳的应用程序在横向(portrait)和竖向(landscape)模式下都显示得美观时,感到狠难做?当妳在设计能够同时支持iPhone iPad 的屏幕布局时,是否感到快要崩溃了?如今,我带给妳一个好消息,妳将不再绝望了!

设计一个针对固定尺寸屏幕的用户界面是狠简单的,但是,如果屏幕的尺寸可能发生变化,那么,妳的用户界面元素的位置和尺寸也要相应地做出调整,以适应新的屏幕尺寸。

在此之前,如果妳的界面设计得相当复杂的话,那么,妳需要写下一大砣代码,用于支持这种自适应布局。告诉妳一个好消息,如今世道不同的,妳再也不需要这样做了——iOS 6iPhone iPad 增加了一个新特性: 自动布局 Xcode 5iOS 7进一步完善了这个特性!如果妳曾经在Xcode 4 中尝试使用 自动布局 并且失望放弃了的话,那么,妳仍然应当在Xcode 5 中再试一次。

自动布局 ,不仅仅使得妳可以轻易地在应用程序中支持不同的屏幕尺寸,还带来了另一个好处,那就是,进行国际化也是举手之劳。妳不再需要为妳想支持的每种语言都制作新的nibs 或故事板(storyboards)了,这里我们还包括了从右向左书写的语言,例如希伯来语或阿拉伯语。

这篇 自动布局 教程,将带妳学会在Interface Builder 中使用 自动布局 功能。

弹簧/支柱springs and struts)模式的问题

在简单的情况下,自动调整尺寸(autosizing)系统可以正常工作,但是,当妳的布局变得复杂时,它狠快就会失效。让我们来看一个简单的例子,在这个例子里,弹簧/支柱模式将失效。

打开Xcode 5,创建一个新的iPhone项目,模板选择为Single View Application。将这个应用命名为“StrutsProblem”

单击Main.storyboard以在Interface Builder中打开它。在做其它操作之前,先禁用掉这个故事板的 自动布局 选项。妳需要在File inspector 中做这件事,即,六个标签页中的第一个标签页中:

取消选中Use Autolayout这个复选框。现在,这个故事板将采用旧的弹簧/支柱模式了。

注意:妳使用Xcode 4.5 或更高版本创建的任何新的nib 或故事板文件中,默认都会启用 自动布局 。因为 自动布局 只支持iOS 6 及以上版本的系统,所以,如果妳想使用最新版本的Xcode 来创建出兼容iOS 5 的应用程序的话,则,妳需要取消选中“Use Autolayout”复选框,以禁用掉任何新的nibs 或故事板文件中的 自动布局 选项。

向主视图中拖入3个新的视图,并且按照下图的位置关系排列它们:

为了让妳清楚地辨别3个视图,我们将它们分别搞上不同的颜色。

每个视图距窗口边缘的距离都是20点;各个视图之间的间隔也是20点。底部那个视图的宽度是280点,上面两个视图的宽度都是130点。3个视图的高度都是254点。

iPhone Retina 4-inch 模拟器上运行这个应用程序,然后将模拟器旋转到横向模式。妳将看到这样一个效果,这肯定不是妳想要的效果吧:

注意:妳可以使用菜单中的Hardware\Rotate LeftRotate Right来旋转模拟器的方向,或者,按住键盘上的,然后按向左或向右的方向键。

实际上,在横向模式中,妳想要的效果是这样的:

显然,这3个视图的自动调整尺寸(autosizing)掩码都需要修改。将左上角那个视图的自动调整尺寸选 项改成以下这样的:

这样,这个视图就会粘附在左边缘和上边缘(而不粘附在下边缘和右边缘),并且,当超视图(superview)改变尺寸时,会在水平方向和竖直方向同时改变大小。

类似地,修改右上角那个视图的自动调整布局选项:

以及底部那个视图的自动调整尺寸选项:

再次运行这个应用程序,然后旋转到横向模式。现在应该看起来是这样的:

已经狠接近想要的效果了,但是还没有完全达到。视图之间的间隔不对。还可以通过另一方面来判断出这个效果不对,那就是,各个视图的尺寸并不是100%正确的。问题在于,自动调整尺寸的掩码告诉了各个视图在超视图改变尺寸时要相应地改变尺寸,但是无法告诉它们该把尺寸改变到多大。

妳还可以尽妳所能去调整这些自动调整尺寸掩码——例如,修改可变的宽度和高度值(即为“弹簧”)——但是,妳无法把它们弄成刚好是3个视图之间的间隔是20点。

遗憾的是,要想解决这个弹簧/支柱模式下的问题,妳需要写一些代码。

在旋转用户界面之前、之时和之后,UIKit会向妳的视图控制器发送多条消息。妳可以截取这些消息,以对用户界面中的布局做些改变。一般情况下,妳需要覆盖viewWillLayoutSubviews,以对任何需要重新布局的视图调整其边框尺寸。

在写那砣代码之前,妳需要先创建几个出口(outlet)属性,以引用到那几个需要调整布局的视图。

切换Assistant Editor模式(Xcode 工具条中Editor 工具集里中间那个按钮),按住Ctrl键,将这3个视图分别拖放到ViewController.m中去:

分别将3个视图连接到以下属性:

@property (weak, nonatomic) IBOutlet UIView *topLeftView;

@property (weak, nonatomic) IBOutlet UIView *topRightView;

@property (weak, nonatomic) IBOutlet UIView *bottomView;

ViewController.m 中加入以下代码:

- (void)viewWillLayoutSubviews

{

if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))

{

CGRect rect = self.topLeftView.frame;

rect.size.width = 254;

rect.size.height = 130;

self.topLeftView.frame = rect;

rect = self.topRightView.frame;

rect.origin.x = 294;

rect.size.width = 254;

rect.size.height = 130;

self.topRightView.frame = rect;

rect = self.bottomView.frame;

rect.origin.y = 170;

rect.size.width = 528;

rect.size.height = 130;

self.bottomView.frame = rect;

}

else

{

CGRect rect = self.topLeftView.frame;

rect.size.width = 130;

rect.size.height = 254;

self.topLeftView.frame = rect;

rect = self.topRightView.frame;

rect.origin.x = 170;

rect.size.width = 130;

rect.size.height = 254;

self.topRightView.frame = rect;

rect = self.bottomView.frame;

rect.origin.y = 295;

rect.size.width = 280;

rect.size.height = 254;

self.bottomView.frame = rect;

}

}

当视图控制器正在向新的朝向发生旋转时,便会调用此回调函数。它会检查视图控制器正要旋转达到的目标朝向,并且相应地改变各个视图的大小——在这个例子中,就是根据当前这个iPhone 的已知尺寸来设置一些硬编码的偏移值。这个回调函数是被放置到一个动画代码块中的,因此,这些改变会以动画的形式呈现出来。

现在还别运行这个应用程序。妳需要将3个视图的自动调整尺寸选项恢复成以下的样子,不然的话,自动调整尺寸机制将会与妳在viewWillLayoutSubviews:中为各个视图设置的位置和尺寸冲突。

这样就可以了。运行这个应用程序,然后切换到横向模式。现在,这几个视图排列得比较漂亮了。重新旋转回到竖向模式,然后验证一下,视图是不是正常显示的。

这样是可以工作,但是,就为了这么简单的一个布局,妳就要写这么多代码。想象一下,遇到一个真正复杂的布局时,要写多少代码,尤其是,单个的视图都会改变尺寸,或者子代视图的个数会发生改变时,有多么复杂。

现在,在一个3.5 英寸的模拟器上运行这个应用程序试试。啊,搞个鸟。3个视图的位置和尺寸都错了,因为,在viewWillLayoutSubviews 中硬编码的坐标数据是按照4英寸的手机设计的(一个是320×568,一个是320×480)。妳也可以再加入一砣if语句来检查屏幕的尺寸并且根据屏幕尺寸来使用一组不同的坐标,但是,想想看,这种方法狠快就会变得不切实际。

注意:还有一种手段,就是,针对竖向和横向的朝向分别提供单独的nibs。当设备的方向发生旋转时,妳载入另一个nib中的视图,用它们来替换掉已有的那些视图。但是,妳仍然需要写狠多代码,并且,妳需要维护两套nibs了。当妳使用故事板,而不使用nibs 时,这种实现方式就更是不实际了。

自动布局能够拯救妳!

现在,妳将看到,如何使用 自动布局 来达到同样的效果。首先,删除ViewController.m 中的viewWillLayoutSubviews,因为,妳不再需要编写任何代码了。

切换Main.storyboard,在File inspector面板中,选中Use Autolayout复选框,以启用这个故事板的 自动布局 选项:

注意:自动布局选项是针对整个nib 或故事板文件起作用的。当妳选中那个复选框时,该nib 或故事板文件中的所有视图都会采用 自动布局 选项。

运行这个应用程序,然后切换到横向模式。现在看起来是这样的:

现在让我们来真正使用 自动布局 吧。按住⌘键,同时依次单击上方的两个视图(绿色和黄色的那两个),这样,两个视图都被选中了。然后,在XcodeEditor菜单中,选择Pin\Widths Equally:

再次选中这两个视图,然后选择菜单Editor\Pin\Horizontal Spacing(当妳做了前面所说的Pin 操作之后,尽管这两个视图看起来象是被选中了一样,但是,要注意,它们只是处于一种特殊的布局关系显示模式中而已。所以,妳仍然需要再次选中这两个视图。)

现在,故事板是这个样子了:

图中,橙色的“工”字形的东西,表示着两个视图之间的约束关系。目前,妳添加了两个约束:在两个视图之间的 等宽 Equal Widths)约束(由带等号的工形符号表示);以及,位于两个视图之间的一个 水平间距 Horizontal Space)约束。约束,表达了视图之间的关系,这就是妳使用 自动布局 时用来构建布局的主要工具。现在看起来有点吓人,但是,当妳学会了这个东西之后,妳就会发现,这些东西是狠直观的。

下一页

S

未知美人

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

HxLauncher: Launch Android applications by voice commands