Auto Layout - BNR
通过Homepwner TARGETS -> General -> Deployment Info -> Devices中的iPhone改为Universal。当在iPad上运行时,自定义的细节界面不能自动调整大小来适应iPad的屏幕大小。因此,需使用Auto Layout来改变其显示方式。
一个约束(constraint)定义了视图层级间特定的关系,其可以用来决定一个或多个视图的布局。
视图校准矩阵的布局属性:
对于BNRDetailViewController.xib文件中,给底部的toolbar添加约束:
1)toolbar的底边缘跟最邻近的单元相距0点(其为toolbar的容器,即BNRDetailViewController视图);
2)toolbar的左边缘跟最邻近的单元相距0点;
3)toolbar的右边缘跟最邻近的单元相距0点;
4)toolbar的高度应为44点。
打开BNRDetailViewController.xib文件,点击图中的左数第三个pin按钮,按下图添加约束:
在上图中,在Spacing to nearest neighbor部分,点击红色虚线,变成红色实现,即添加了一个距离约束。并将Height左边的方框打钩,给Height添加约束。最后,点击底部的Add 4 Constraints使添加的约束生效。
当创建了一个约束时,它将被添加到视图层级中特定的视图对象上。该约束影响了那个视图,则该视图就拥有这个约束。
按下图给Name标签添加约束:
按下图给Name右边的field添加约束:
接着,选中Name标签和该field,点击图中的左数第二个Align图标,如下,给Baselines添加约束:
每一个约束都有一个优先级(Priority level),其用于当约束发生冲突时,哪个约束会获胜。优先级从1到1000,1000是必须的一个优先级。
约束调试:
Ambiguous layout——意味着至少缺少一个约束。
在BNRDetailViewController.xib文件中添加两个Label,如下图:
选中两个Label,按照添加约束下图添加top、left、right约束:
在BNRDetailViewController.m文件中添加viewDidLayoutSubviews方法如下:
1 //当视图改变大小时自动被调用(如第一次在屏幕上显示,或屏幕旋转) 2 - (void)viewDidLayoutSubviews { 3 //检查子视图是否有任何模凌两可的布局 4 for(UIView *subview in self.view.subviews) { 5 if ([subview hasAmbiguousLayout]) { 6 NSLog(@"AMBIGUOUS: %@", subview); 7 } 8 } 9 }
运行程序,将报告两个label的布局是模凌两可的。
修改backgroundTapped:方法如下:
1 - (IBAction)backgroundTapped:(id)sender { 2 [self.view endEditing:YES]; 3 4 for(UIView *subview in self.view.subviews) { 5 if ([subview hasAmbiguousLayout]) { 6 [subview exerciseAmbiguityInLayout]; 7 } 8 } 9 }
当点击背景视图时,模凌两可的两个label将互相转换。
从一个labelControl-Drag到另一个label,选中Equal Widths,使两个label的宽度相等。
exerciseAmbiguityInLayout方法纯粹是调试的工具,允许Auto Layout向你展示可能存在的布局。不应将该代码留在程序中。
Unsatisfiable constraints:当两个或更多个约束冲突时发生。意味着一个视图约束太多。
Misplaced Views:在XIB文件中视图的位置与其约束不匹配。意味着程序运行时,视图的框架跟在画布(canvas)上显示的不一样。
在不同的设备上,为了使视图控制器加载恰当的XIB文件,可以给xib文件加后缀,文件名为 BNRDetailViewController~iphone.xib BNRDetailViewController~ipad.xib 。
但是,该方法不能替代Auto Layout。Auto Layout亦会对用户的语言、字体大小或设备朝向作出反应。