IOS7 Xcode5 下使用AutoLayout

来源:互联网 发布:python高斯分布散点图 编辑:程序博客网 时间:2024/04/30 21:45

经过亲身体验,在同时支持IOS6 和IOS7的时候还使用frame来布局是件非常痛苦的事情。。

所以在http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1 学习了一下ios7的自动布局,它与在ios6的时候有些不同。

下面就简单的记录下,学习过程。

首先说明下主要的差别:

1、XCODE5中的autolayout ,拖入控件的时候系统是不会添加默认的约束(constraint)的。

2、要添加更加详细的约束,来让编译器明确的知道这个view是放在什么地方和其他view之间的关系,这意味着可能会需要更多的约束。

3、如果在UI设计阶段你没有添加任何约束,那么在编译阶段编译器会自动加入约束,来保证界面是你在stroyboard中设计的样子。(仅限Xcode5)


AutoLayout 使用:

第一部分:

(添加约束,主要在Editor中第一块进行,

align--对齐方式,

pin--主要的布局手段,等宽,边距,高度宽度等设置,

resolve auto layout-- 当你遇到警告的时候,不妨看看这有没有解决办法)当然stroyboard的右下角,是有快捷菜单的。


为了明确view的约束,要给其添加如下的约束。这张图可以很好的说明 (浪费了我好多看文字的时间,英语差伤不起啊)


值得说的是,当你看到你添加的约束是橙色的线的时候,这说明你的约束条件还不能够准确的描述局部,直到约束都变成蓝色后才是一个完整而且准确的布局。

(PS: 当线上有数组的时候,说明是stroyboard中的视图和约束中给的数值不一致,需要调整。也可以使用 右下角的工具来自动更新,可以选择更新视图或者更新约束)




由于Xcode5对自动布局的改进,界面上非常固定的元素 可以不添加约束,只对那些有特殊规则的view添加约束即可。但一旦你为某个元素添加了约束,那么你就在告诉编译器,不要为这个元素添加默认约束了。也就是说,一旦你添加了一个约束,那么你就要让它完整而且正确。

You simply don’t add constraints if the default ones are sufficient and only create constraints for those views that need special rules.


当你决定了控件的位置,又为其添加了某些约束之后,又发现你需要调整一下它的位置,当时在拖动之后发现先前的约束变成了橙色的。这个时候你就需要更新你的视图或者约束了。做法是这样的:

在右下键工具条第二栏的第三个菜单中,选择是要更新你的约束来匹配你拖拽后的布局,还是更新视图来匹配你的约束。这在橙色的虚线中会有所发现。就是那个小小的数字~显示了当前视图和约束中的条件的差异。具体怎么决定就要看你的了~ 当然也可以删除先前冲突的约束,为之后的新视图重新添加约束,但是这显然是很麻烦的。

有一些控件会有自己固有的宽高,比如。。。。

UIButton -- 宽度就是title+留白,或者图片(背景)的尺寸

又或者UILabel。。 这种控件知道自己的宽度和高度,所以不用特别为其制定。使用Editor/Size to Fit COntent 就会自动适应。除非你有尺寸要求,否则这种布局会是很好的选择。

view和superview可以有约束,同级的view之间也可以使用约束。使用和之前是一样的,但是有一个快捷的方法,点击控件,按住Ctrl 拖拽到目的视图 会弹出一个popup,就可以选择你需要的约束了。


当你发现有橙色的引导线的时候,但是并不知道应该添加什么约束,那么这幅图应该可以帮助你的。


第二部分:


上一部分说过,编译器会根据约束来确定控件的位置position和大小size。可以用来自动确定某些不确定大小的控件,比如Label……设置Label的numbersOfLine=0 ,然后设置约束,左间距20,上间距20,宽度300,高度不设置或者设置greater than or equel.. 这样根据不同的内容,label就会自动调节高度并且其他控件也可以自动调整布局了。

A label knows how wide and tall it is because it knows the length of the text that has been set on it, as well as the font size for that text. Likewise for a button, which might combine the text with a background image and some padding.

The same is true for segmented controls, progress bars, and most other controls, although some may only have a predetermined height but an unknown width.

很重要的一个概念:intrinsic content size

大部分控件都有intrinsic content size ,暂且称为控件的自有尺寸。当你不想用控件的自有尺寸的时候,可以指定width和height约束,来固定控件的尺寸。 Pin/Width  or  Pin/Height

storyboard右下角的菜单,pin中的Spacing to nearest neighbor的四个T-bar,就是当前view对superview的spacing约束,或者是和同级别view的spacing。

UIView是没有intrinsic content size的。所以要有约束准确的描述UIView对象的size。


值得注意的是Top Layout Guide 和Bottom Layout Guide,因为IOS7的布局是从status bar下面开始,看下面的介绍。

Note: Maybe you wondered why the constraint at the top of the view didn’t go all the way up to the top of the screen:

Space at top

Instead it stops at the status bar. But in iOS 7 the status bar is always drawn on top of the view controller — it is no longer a separate bar — so what gives? When you created the constraint it didn’t actually attach to the top of the screen but to an invisible line called the Top Layout Guide.

On a regular view controller this guide sits at 20 points from the top of the screen, at least when the status bar is not hidden. In a navigation controller it sits below the navigation bar. Because the navigation bar has a different height in landscape, the Top Layout Guide moves with the bar when the device is rotated. That makes it easy to place views relative to the navigation bar. There is also a Bottom Layout Guide that is used for the tab bar and toolbars.


当一个控件的约束过多的时候(其中有一些是冲突的),那么当屏幕旋转或者是其他形式引起的视图改变,触发这些冲突的约束时就会报错,类似这样

robably 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)]>")

解决办法,就是查看哪些约束是冲突的,删除其中不必要的冲突即可。。(还没找到自动化的办法,哪位同学发现了可以告诉我不~?)


有时候编译器需要值得,同级别的控件之间的优先级来确定当父类改变尺寸的时候,子类之间是如何改变的 ,原文如下……

You have a Content Priority Ambiguity error. That’s quite the mouthful. This is what it means: If neither the image view nor the label has a fixed height, then Auto Layout doesn’t know by how much to scale each if the height of the green view should change. (Interface Builder seems to ignore for now that the green view actually has a fixed Height constraint set on it.)

Let’s say at some point in your app the green view becomes 100 points taller. How should Auto Layout distribute these new 100 points among the label and the image view? Does the image view become 100 points taller while the label stays the same size? Or does the label become taller while the image view stays the same? Do they both get 50 points extra, or is it split 25/75, 40/60, or in some other possible combination?

If you don’t solve this problem somehow then Auto Layout is going to have to guess and the results may be unpredictable.

The proper solution is to change the “Content Compression Resistance Priority” of the label. You will learn more about that later on. For now, go into the Size inspector for the label and set the verticalContent Compression Resistance Priority to 751. That makes it one higher than the priority of the image view. While you’re at it, set Content Hugging Priority to 252.

由于英文比较差,贴出原文吧 比较准确……


就到此为止吧~ 关于Xcode5中的AutoLayout的使用,这只是一个初步的原理和步骤,要想熟练的使用并制作出复杂而优雅的UI,要多多联系啊。。现在我就去联系了。。




原创粉丝点击