iOS自动布局

自动布局


技术博客http://www.cnblogs.com/ChenYilong/ 
新浪微博http://weibo.com/luohanchenyilong 




自动布局 
技术博客 http://www.cnblogs.com/ChenYilong/ 新浪微博 http://weibo.com/luohanchenyilong
 
问题 
•  iOS 程序中,大部分视图控制器都包含了 大量的代码用 于设置 UI 布局 ,设置控件的水平或垂直位置,以确保组件 在不同版本的 iOS 中都能得到合理的布局
•  甚至有些程序员希望在不同的设备使用相同的视图控制器, 这就给代码添加了更多的复杂性!
  自动布局 AutoLayout 的引入很好地解决了这一问题!  

iOS自动布局

测试演练 1-- 使用 AutoSizing  
•  Main.sotryboard 的正中间中添加一个按钮,并使用 AutoSizing 尝试调
整按钮位置  
•  经过运行测试不难发现, 不仅在不同分辨率的设备上运行效果不同, 而且在不同的版本上运行的表现也不一致  

定义 
•  AutoLayout 是一种基于约束的,描述性的布局系统
-   基于约束 :和以往定义 frame 的位置和尺寸不同, AutoLayout 的位 置确定是 以所谓相对位置的约束来定义的 ,比如 x 坐标为 superView   的中心, y 坐标为屏幕底部上方 10 像素等  
-   描述性 :约束的定义和各个 view 的关系 使用接近自然语言或者可视 化语言 的方法来进行描述  
-   布局系统 :用来负责界面的各个元素的位置  
•  AutoLayout 为开发者提供了一种不同于传统对于 UI 元素位置指定的布 局方法。以前,不论是在 IB 里拖放,还是在代码中写,每个 UIView 都 会有自己的 frame 属性,来定义其在当前视图中的位置和尺寸。而使 用 AutoLayout ,就变为了使用约束条件来定义 view 的位置和尺寸  

AutoLayout 的优势 
  解决不同分辨率和屏幕尺寸下 view 的适配问题,同时也简化了旋转时   view 的位置的定义。 原来在底部之上 10 像素居中的 view ,不论在旋转 屏幕或是更换设备( iPad iPad mini iPhone 4 或者是 iPhone5 )的时 候,始终还在底部之上 10 像素居中的位置,不会发生变化
  使用约束条件来描述布局, view frame 会依据这些约束来进行计算

测试演练 2-- Storyboard 中使用自动布局 
•  Storyboard 中为一个屏幕居中的按钮添加水平居中和垂直居中的布
局约束
•  经过运行测试不难发现, 添加了自动布局之后,在不同分辨率的设备 以及不同的版本的设备上运行时该按钮始终会保持在屏幕中间

测试演练 3-- Storyboard 中使用自动布局 
•  以前一演练为基础,分别在垂直方向上,上下各放置间距 20 点的两个
按钮
•  经过运行测试不难发现, 在不同分辨率的设备以及不同的版本的设备 上运行时该按钮始终会保持在屏幕中间,而且无需编写任何的代码!

AutoLayout Autoresizing Mask 的区别 
  iOS6 之前 ,关于屏幕旋转的适配和 iPhone , iPad 屏幕的自动适 配,基本都是由 Autoresizing Mask 来完成的。但是随着大家对   iOS App 的要求越来越高,以及今后可能出现的多种屏幕和分辨 率的设备, Autoresizing Mask 显得有些落伍和迟钝了。   AutoLayout 可以完成所有原来 Autoresizing Mask 能完成的工作, 同时还能胜任一些原来无法完成的任务,其中包括:
  AutoLayout 可以指定任意两个 view 的相对位置 ,而不需要像   Autoresizing Mask 那样需要两个 view 在直系的 view hierarchy
  AutoLayout 不必须指定相等关系的约束 ,它可以指定非相等约 束(大于或者小于等);而 Autoresizing Mask 所能做的布局只 能是相等条件的
  AutoLayout 可以指定约束的优先级 ,计算 frame 时将优先按照满 足优先级高的条件进行计算

AutoLayout 的基本使用 
•  在创建约束之后,需要将其添加到作用的 view 上。
在添加时要注意目标 view 需要遵循以下规则:
•  1 )   对于两个同层级 view 之间的约束关系 ,添加 到他们的父 view
iOS自动布局
添加约束的规则( 2
•  2)   对于两个不同层级 view 之间的约束关系 ,添加 到他们最近的共同父 view
iOS自动布局
添加约束的规则( 3
•  3)   对于有层次关系的两个 view 之间的约束关系 , 添加到层次较高的父 view  
iOS自动布局
创建约束 ( 用手码必须保证所有的约束都成功 )   + ( id )constraintWithItem:attribute:relatedBy:toItem:
attribute:multiplier:constant:! !
参数说明: !   WithItem : 要约束的对象 !   attribute : 对象的布局属性 !   relatedBy : 布局关系 !   toItem : 参照对象 ! attribute : 参照对象的布局属性 !   multiplier : 乘数 ! constant : 常数 !
!

自动布局的核心公式 !
Object1.property1 = ( object2.property2 * multiplier ) + constant value!


•  View.center.x = self.view.center.x   *   1 + 0;  •  View.center.y = self.view.center.y   *   1 + 0;  
添加和刷新约束 
  添加约束   -(void)addConstraint:(NSLayoutConstraint *)constraint
  刷新约束的改变   -setNeedsUpdateConstraints -layoutIfNeeded
[button setTranslatesAutoresizingMaskIntoConstraints : NO ];

测试演练 4-- 使用代码添加约束  // 2.1   水平方向的约束  
NSLayoutConstraint   *constraintX = [ NSLayoutConstraint constraintWithItem :button attribute : NSLayoutAttributeCenterX relatedBy : NSLayoutRelationEqual toItem : self . view attribute : NSLayoutAttributeCenterX multiplier : 1.0f   constant :   0.0f ];
!
[
self . view   addConstraint :constraintX]; !
// 2.2   垂直方向的约束  
NSLayoutConstraint   *constraintY = [ NSLayoutConstraint constraintWithItem :button attribute : NSLayoutAttributeCenterY relatedBy : NSLayoutRelationEqual toItem : self . view attribute : NSLayoutAttributeCenterY multiplier : 1.0f   constant :   0.0f ];
!
[
self . view   addConstraint :constraintY];  

Visual Format Language   可视格式语言 
•  这种语言是对视觉描述的一种抽象,例如: accept 按钮在   cancel 按钮右侧默认间距处 ,使用 VFL 描述的大概过程如下:
   
测试演练 5--VFL 演练( 1
// 1.   创建三个按钮: top center bottom  
// 2.   三个按钮宽度为 100  
// 3.   三个按钮距离屏幕右侧 20  
// 4. bottom 按钮距离屏幕底部 20 点,每个按钮纵向间距为 20
NSDictionary   *viewDict = NSDictionaryOfVariableBindings (top, center, bottom);
!
NSArray   *consh1 = [ NSLayoutConstraint constraintsWithVisualFormat : @"H:[top(100)]-20-|"   options : 0   metrics : nil views :viewDict];
 
NSArray   *consv = [ NSLayoutConstraint constraintsWithVisualFormat : @"V:[top(40)]-20-[center(40)]-20- [bottom(40)]-20-|"   options : 0   metrics : nil views:viewDict];
......  

测试演练6 --VFL 演练( 2
// 1.   创建两个按钮: btn1 btn2   // 2.   两个按钮宽度为 100   // 3. btn1 高度 80 点, btn2 高度 60   // 4.   两个按钮间距 20 点, btn2 距离屏幕右侧 20 NSDictionary *dict2 = NSDictionaryOfVariableBindings(btn1, btn2);   
NSArray *consH = [NSLayoutConstraint constraintsWithVisualFormat: @"H:[btn1(100)]-[btn2(100)]-20-|"   options: 0 metrics: nil   views:dict2];
 

VFL 示例 
  [cancelButton(72)]-12-[acceptButton(50)]  
  取消按钮宽 72point , accept 按钮宽 50point ,它们之间间距 12point  
  [wideView(>=60@700)]  
  wideView 宽度大于等于 60point ,该约束条件优先级为 700 (优先级最大值为   1000 ,优先级越高的约束越先被满足)  
  V:[redBox][yellowBox(==redBox)]  
  竖直布局,先是一个 redBox ,其下方紧接一个宽度等于 redBox 宽度的  
yellowBox  
  H:|-[Find]-[FindNext]-[FindField(>=20)]-|  
  水平布局, Find 距离父 view 左边缘默认间隔宽度,之后是 FindNext 距离 Find 间 隔默认宽度;再之后是宽度不小于 20 FindField ,它和 FindNext 以及父 view 右 边缘的间距都是默认宽度。(竖线“ | " 表示 superview 的边缘)  

使用 AutoLayout 容易出现的错误 
  Ambiguous Layout   布局不能确定 ,即给出的约束条件无法唯一 确定一种布局,也就是约束条件不足,无法得到唯一的布局结 果。 这种情况一般添加一些必要的约束或者调整优先级可以解 决  
  Unsatisfiable Constraints   无法满足约束 ,问题来源是有约束条 件互相冲突,因此无法同时满足, 需要删掉一些约束  
  现在使用 IB 可以比较容易地完成复杂约束,在实际开发中很少 再会遇到遗漏或者多余约束情况的出现,有问题的约束条件将 直接在 IB 中得到错误或者警告  

视图动画 
•  需要记住的是: Core Animation Auto Layout 结合在一起产生视图动 画时,不要直接修改视图的 frame 一旦视图使用自动布局,意味着 已经将设置 frame 的责任交给了布局系统 。你的干扰将造成怪异的行 为。
  一旦使用了自动布局,就要忘记 Frame 的概念!
•  此时应该使用: [myView layoutIfNeeded];  
回顾 
•  随着 iOS7 的普及,会有越来越多的应用基于 Storyboard 开发   目前几乎所有的 iOS 开发的公司都面临着从 iOS6 iOS7 的迁移及适配工
,基于 AutoLayout 开发的应用程序,迁移工作会相对简单
  AutoLayout 随然没有直接定位坐标直观,但是熟悉之后,对屏幕适配 的支持将会非常方便,而且在开发过程中能够节约大量的代码,使得 程序员将更多的精力集中在程序功能的实现上,而不再是花费大量的 时间和精力去做屏幕适配的工作

© chenyilong. Powered by Postach.io

你可能感兴趣的:(ios)