SizeClass 和AutoLayout教程3
(这个系列的文章都来自《iOS8 by tutorials》的第一章,大部分直接翻译,会加入我自己的解释和理解,有兴趣的可以上Raywenderlich网站购买正版图书。购买链接http://www.raywenderlich.com/store )
我们接着上期的教程,继续完善这个天气程序。 这是我们项目的github地址:https://github.com/pingguo-zangqilong/AutoLayoutLesson
现在给我们的ImageView添加一个新的约束。用鼠标右键选中Imageview然后拖到viewcontroller的view上,选择Equal Heights,这个约束的意思就是我们的ImageView要与self.view等高。如图

添加完这个约束之后会发现我们的左边界面又出现的红色箭头,说明我们的约束有问题了。先不用管,选中我们刚才添加的等高约束,然后找到属性栏,如图所示

先看看上面写得什么:First Item:Superview.Height
Relation:Equal
Second Item:cloud.Height
这和我们期望的不一样,为什么?这个意思是,superview的高度要与cloud这个ImageView的高度相同,因果关系错了,因为我们想要的应该是cloud的高度要与superview的高度相同,我们点一下Reverse First Item and SecondItem,如图

交换一下第一个item和第二个item的位置。这样因果关系就对了。然后我们把Multiplier改成0.4.大家现在知道这个约束是什么意思了么?
意思就是我们这个ImageView的高度要等于self.view.frame.size.height*0.4+constant(这里我们没有设置所以是0)。
但是我们这时候不想让他等于,我们想让imageview的高度变成小于等于,所以把relation的Equal改成Less Than or Equal,也就是我们的高度要小于等于而不是等于。如图

好了,这下红色箭头没了,说明我们添加的约束没有问题了。
显示天气,光有个ImageView肯定是不够的,起码得有两个label来显示一些详细信息。这时候我们再给这个controller添加两个label。如图

先选中上面的那个label,给他添加下面两个约束。如图

然后设置label 的内容为“Cupertino”(应该是个地名,我也不知道这是哪-_-!).字体颜色为白色,字体为Helvetica Neue,Thin ,size是150.
好的,设置完第一个label的约束,我们给第二个label也添加两个约束,一个是距离父view的bottom间距为10,一个是水平居中。如图所示,添加完以后应该是这样的。

然后我们把label内容设置为“28C”,字体颜色为白色,字体和第一个label一样,Helvetica Neue,Thin,size是250.
然后左边出现了黄色箭头,说明我们label的运行大小和现在大小不符合,那么我们选中viewcontroller的view,然后选择update frames。好了,现在视图应该是这样子。

这什么鬼!。不急,先在Xcode6新加的视图预览功能里看看,ipad里看起来是这样的。

哎呦,不错哦。但是在iphone里看起来是这样的。

what the hell!

肯定是因为我字体设置的太大了。怎么办呢?
来看下我们iOS8的新特性,苹果公司用sizeclass把屏幕大下不同的设备分成这么几类。如图

这个图看看就行了。不用记住,用得多了自然就记住了。
然后点击我们这个按钮,如图

我们先选择这个类型。Any Width | Compact Height 如图

这时会有两个明显的变化,第一个变化时我们的视图形状变了,变成这样了。

然后底部的字样变了。变成这样了

我们现在好好梳理一下到底发生了什么。首先我们的布局从Anywidth AnyHeight 变成了AnyWidth compactHeight。其实从字面意思不难猜到,AnyWidth和Anyheight肯定代表了所有设备,因为任何宽度任何高度不就涵盖了所有的设备么,那么AnyWidth 和compact height代表的范围肯定要窄一些。那么到底有哪些呢?如图

就是这种类型只代表iphone横放的状态,也就是Landscape模式。compact在英文里的意思就是紧凑的意思,意思就是任意宽度,但是高度较小。现在脑补一下,手机横放了不就是宽度增加(any),高度变小了么(compact)。所以高度变成了compact height。
现在想想,苹果为什么要这么设计?很简单,因为再牛逼的布局也不能保证一套阵容打天下。你想在ANYWIDTH,ANYHEIGHT的情况下设计一套布局能够适用所有的设备并且适用横放竖放模式那是不可能的,除非你的界面超级简单。所以有了这种特例情况的布局。
那么怎么才能设计特例情况下的布局呢,我们先直接动手。首先,选中ImageView,找到Align Center X to:Superview这个约束,如图

按Delete删掉,这时候你会发现这个约束并没有消失,而是变成了浅灰色。如图

我们双击这个变成灰色的约束,出现了下面的视图。

上面的Installed是打了勾的,下面的Installed这个选择框没打勾,说明了什么?说明了在我们当前这个模式下,这个约束没有被安装(Installed),就说明这个约束现在在这个模式下不生效,所以左边又出现了红色箭头。好,我们继续上面的操作,一不做二不休,把imageview剩下的三个约束全部按delete删掉。现在是这个样子。

我们重新为这个ImageView添加只适用于AnyWidth和CompactHeight模式下得约束。如图

然后用右键选中imageView拖一条线到controller的view,选择Equal Widths,找到这个约束,跟以前的步骤一样,先看看firstitem是不是
imageview,如果不是就reverse first and second item,然后把multiplier改成0.45.
现在imageview的约束搞定了,我们添加了3个约束,一个是宽度等于父view的width*0.45,一个是垂直居中,还有一个约束是左边界与父view左边界距离10.
现在TextContainer这个view的约束又出现了红箭头,说明我们在这个sizeclass的布局有问题。先在左边找到TextContainer的这个约束,就是textcontainer左边界与父view左边界的这个约束,按住CMD+DELETE键
卸载掉这个约束。如图

然后给TextContainer添加新的约束,如图

按住shift键不放,在出现的窗口选中Top Space to Top Layout Guide和Equal Widths这两个约束。如图

编辑这两个约束。
1.把Top Layout Guide 的constant设为0.
2.把Equal Width to:Superview的Multiplier设置为0.5.注意firstitem要为TextContainer。
然后update frames,你会发现界面是这样了。

这章先讲到这,下章讲怎么设置不同size class的不同Font。