1 使用Autoresizing的方式进行界面布局

1.1 问题

Autoresizing是IOS旧版的自动布局技术,现在仍然被很多企业使用。本案例将学习如何使用Autoresizing完成界面的布局,如图-1、图-2所示:

图-1

图-2

1.2 方案

首先创建一个SingleViewApplication项目,会自动帮我们创建好一个TRViewController类,并且自动带有Storyboard文件,默认情况下Storyboard里面有一个已经创建好的场景,已和TRViewController类绑定。

由于Autoresizing和自动布局是冲突的,所以首先将自动布局功能关闭,选中Storyboard中的场景,在右边栏的第一个检查器中将Use AutoLayout和Use Size classes选项前面的勾去掉;

其次设置界面,在Storyboard的场景的上方拖放两个Button控件,中间拖放一个ImageView,右下角拖放三个小的Button控件。

然后依次选中场景中各个控件,在右边栏的第五个检查器中进行Autoresizing的布局设置,根据界面需要点亮需要的红线;

最后使用代码方式补充Autoresizing无法完成的布局任务。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建项目,关闭自动布局功能

首先创建一个SingleViewApplication项目,Xcode会自动帮我们创建好一个TRViewController类,并且自动带有Storyboard文件。默认情况下Storyboard里面有一个已经创建好的场景,并且已经和TRViewController类绑定。

由于Autoresizing和自动布局是冲突的,所以首先将自动布局功能关闭,选中Storyboard中的场景,在右边栏的第一个检查器中将Use Auto Layout和Use Size classes选项前面的勾去掉,如图-3所示:

图-3

步骤二:设置界面

首先在Storyboard的场景拖放两个Button控件,两个Button的大小一样,并排放置在场景的上方。

然后界面中间拖放一个ImageView,给ImageView设置一张图片。界面的右下角拖放三个小的Button控件,大小也保持一致,界面完成构建如图-4所示:

图-4

步骤三:设置Autoresizing,进行布局

首先选中场景中左上方的Button的控件,在右边栏的第五个检查器中进行Autoresizing的布局设置,根据界面需要,点亮Button左边、上方的红线,表示Button控件相对于父视图保持左边距和上边距不变。然后在点亮Button中间的横线,表示Button的宽是控件的宽度随着父视图的宽度按比例改变,如图-5所示:

图-5

再选中场景中右上方的Button的控件,同样在右边栏的第五个检查器中进行Autoresizing的布局设置,根据界面需要,点亮Button右边、上方的红线,表示Button控件相对于父视图保持右边距和上边距不变。然后在点亮Button中间的横线,表示Button的宽是可以随视图变化而变化的,如图-6所示:

图-6

然后依照同样的步骤,设置ImageView的Autoresizing,对ImageView进行布局设置,使ImageView始终保持在屏幕中间显示,如图-7所示:

图-7

最后设置右下角三个Button的Autoresizing,使这个三个button始终保持在屏幕的右下角,并且间距和大小保持不变,如图-8所示:

图-8

步骤四:使用代码完成其他布局要求

Autoresizing只能描述子视图与父视图之间的关系,并不能描述子视图之间的布局关系,因此在Autoresizing不能满足布局要求的时候,需要使用代码来补充完成,本案例中当完成了如上的Autoresizing设置之后,将屏幕切换成横屏之后,发现上方两个Button的距离发生了变化,并不是我们想要实现的效果,如图-9所示:

图-9

为了使两个Button之间的距离保持不变,此时只能在TRViewControll类中重写viewDidLayoutSubviews方法,使用代码来完成此项布局设置,代码如下所示:

 
  1. - (void)viewDidLayoutSubviews
  2. {
  3. [super viewDidLayoutSubviews];
  4. CGFloat buttonWidth = (self.view.bounds.size.width - 50)/2;
  5. CGRect frame = CGRectMake(20, 20, buttonWidth, 40);
  6. self.button1.frame = frame;
  7. frame.origin.x += buttonWidth + 10;
  8. self.button2.frame = frame;
  9. }

这样就能使两个Button之间无论是横屏还是竖屏都能保持固定的间距,最终完成效果如图-10所示:

图-10

1.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @interface TRViewController ()
  3. @property (weak, nonatomic) IBOutlet UIButton *button1;
  4. @property (weak, nonatomic) IBOutlet UIButton *button2;
  5. @end
  6. @implementation TRViewController
  7. - (void)viewDidLayoutSubviews
  8. {
  9. [super viewDidLayoutSubviews];
  10. CGFloat buttonWidth = (self.view.bounds.size.width - 50)/2;
  11. CGRect frame = CGRectMake(20, 20, buttonWidth, 40);
  12. self.button1.frame = frame;
  13. frame.origin.x += buttonWidth + 10;
  14. self.button2.frame = frame;
  15. }
  16. @end
 

2 代码方式使用Autoresizing进行界面布局

2.1 问题

当子视图直接是用代码的方式创建时,就无法在Storyboard或xib中对其进行Autosizing的设置和操作,此时就需要用代码的方式使用Autoresizing技术。本案例将学习如何使用代码的方式进行Autoresizing布局,使界面上的两个按钮始终保持在屏幕的右上角和右下角,如图-11、图-12所示:

图-11

图-12

2.2 方案

首先同样的创建一个SingleViewApplication项目,在TRViewController.m文件的viewDidLoad方法中创建两个UIButton控件,分别放置在屏幕的右上角和右下角。

然后通过设置Button的autoresizingMask属性,进行Autoresizing布局,相当于在检查器中点亮Autoresizing的红线。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建项目,添加按钮控件

首先创建一个SingleViewApplication项目。在TRViewController.m文件的viewDidLoad方法中创建两个UIButton控件,分别设置两个button的frame属性,将两个button放置在屏幕的右上角和右下角,代码如下所示:

 
  1. UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
  2. btn1.frame = CGRectMake(self.view.bounds.size.width - 20 - 80, self.view.bounds.size.height - 20 - 35, 80, 35);
  3. btn1.backgroundColor = [UIColor lightGrayColor];
  4. [self.view addSubview:btn1];
  5. UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeSystem];
  6. btn2.frame = CGRectMake(self.view.bounds.size.width - 20 - 80, 20, 80, 35);
  7. btn2.backgroundColor = [UIColor lightGrayColor];
  8. [self.view addSubview:btn2];

步骤二:设置Button的autoresizingMask属性,进行Autoresizing布局

通过设置Button的autoresizingMask属性,进行Autoresizing布局,autoresizingMask属性是UIViewAutoresizing的枚举类型。

首先使用代码分别将btn1相对于父视图的上边距和左边距固定,即将btn1.autoresizingMask设置为UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin。

然后使用代码分别将btn2相对于父视图的下边距和左边距固定,即将btn2.autoresizingMask设置为UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin,代码如下所示:

 
  1. //设置button的Autoresizing布局属性,将按钮btn1相对于父视图的上边距和左边距固定
  2. btn1.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
  3. //将btn2相对于父视图的左边距和下边距固定
  4. btn2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;

2.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @implementation TRViewController
  3. - (void)viewDidLoad
  4. {
  5. [super viewDidLoad];
  6.     UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
  7. btn1.frame = CGRectMake(self.view.bounds.size.width - 20 - 80, self.view.bounds.size.height - 20 - 35, 80, 35);
  8. btn1.backgroundColor = [UIColor lightGrayColor];
  9. [self.view addSubview:btn1];
  10. UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeSystem];
  11. btn2.frame = CGRectMake(self.view.bounds.size.width - 20 - 80, 20, 80, 35);
  12. btn2.backgroundColor = [UIColor lightGrayColor];
  13. [self.view addSubview:btn2];
  14. //设置button的Autoresizing布局属性,将按钮btn1相对于父视图的上边距和左边距固定
  15. btn1.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
  16. //将btn2相对于父视图的左边距和下边距固定
  17. btn2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
  18. }
  19. @end
 

3 演示自动布局技术(AutoLayout)

3.1 问题

自动布局技术(AutoLayout)是从iOS6开始的一个新的布局技术,在iOS7中开始广泛使用,从iOS8开始和size classes结合使用。

本案例将学习如何使用自动布局技术(AutoLayout)进行界面布局,如图-13、图-14所示:

图-13

图-14

3.2 方案

首先创建一个SingleViewApplication项目,在Storyboard的场景界面中的左上角、左下角、右上角、右下角和中间分别放置一个Button控件。

然后通过工具依次给每一个Button添加自动布局的约束,完成布局。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建项目,添加按钮控件

首先创建一个SingleViewApplication项目,在Storyboard的场景界面中的左上角、左下角、右上角、右下角和中间分别放置一个Button控件,并在右边栏的检查器四中设置Button的属性,界面搭建完成如图-15所示:

图-15

步骤二:进行自动布局

首先选中Storyboard中的场景,在右边栏的检查器一中将Use Auto Layout和Use Size classes选项勾上(默认情况下是勾上的),如图-16所示:

图-16

然后选中左上角的按钮,点击编辑界面右下方的添加约束工具栏上的第二个按钮,在弹出的窗口上,给按钮添加上边距和左边距的约束(点亮红线即可),点击Add 2 Constraints即完成将约束对象添加到视图上,如图-17所示:

图-17

再选中右上角的按钮,以同样的方式给按钮添加上边距和右边距的约束。然后选中上方的两个按钮,点击编辑界面右下方的添加约束工具栏上的第一个按钮,设置两个按钮的对齐方式水平居中对齐,如图-18所示:

图-18

此时选中按钮,可以在右边的检查器五中查看约束情况,也可以对约束进行编辑和调整,如图-19所示:

图-19

然后按照以上方式设置下方两个按钮的约束和对齐方式。在选中左边上下的两个按钮,将两个按钮的对齐方式设置为垂直居中对齐,如图-20所示:

图-20

右边两个按钮也以同样的方式设置为垂直居中对齐。最后设置中间按钮的布局,始终保持在屏幕的水平中心和垂直中心即可,如图-21所示:

图-21

这样就完成了整个界面的布局设置。

4 代码的方式使用自动布局技术

4.1 问题

当界面上的控件是由代码创建时,此时就只能使用代码的方式对该控件进行布局设置。本案例将学习如何通过代码的方式逐步添加约束,进行自动布局设置,使界面中的按钮始终保持在右上角,如图-22、图-23所示:

图-22

图-23

4.2 方案

首先同样的创建一个SingleViewApplication项目,在TRViewController.m文件的viewDidLoad方法中创建一个UIButton控件,设置相关属性,将按钮放置在屏幕的右上角。

然后确认Use AutoLayout功能被打开,在viewDidLoad方法中用代码将按钮的Autoresizing的翻译功能关闭,如果不将其关闭自动布局会自动将Autoresizing功能翻译成约束,造成约束冲突。

再在viewDidLoad方法中通过NSLayoutConstraint类的工厂方法constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:给button对象创建每一个约束。

最后将约束对象添加到父视图中。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建项目,添加按钮控件

首先创建一个SingleViewApplication项目。在TRViewController.m文件的viewDidLoad方法中创建一个Button控件,并将其添加到父视图中,这里需要注意自动布局功能开启时,在viewDidLoad方法中设置控件的frame属性无效,frame是根据自动布局设置自动计算出来的,代码如下所示:

 
  1. UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
  2. button.backgroundColor = [UIColor lightGrayColor];
  3. [button setTitle:@"我是按钮" forState:UIControlStateNormal];
  4. [self.view addSubview:button];

然后在检查器中确认Use AutoLayout功能被打开。在viewDidLoad方法中用代码将按钮的Autoresizing的翻译功能关闭,即将button的translatesAutoresizingMaskIntoConstraints属性设置为NO。如果不将其关闭自动布局会自动将Autoresizing功能翻译成约束,造成约束冲突,代码所示:

 
  1. button.translatesAutoresizingMaskIntoConstraints = NO;

步骤二:使用代码的方式添加约束

在viewDidLoad方法中通过NSLayoutConstraint类的工厂方法constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:给button对象创建每一个约束,本案例中需要给button创建四个约束,代码如下所示:

 
  1. //距离右边20点:button.right = self.view.right * 1.0 + (-20);
  2. NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20];
  3. //距离上边20点:button.top = self.view.top * 0.0 + 20;
  4. NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:0.0 constant:20];
  5. //固定宽度100
  6. NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0.0 constant:100];

最后将约束添加到父视图中,代码如下所示:

 
  1. [self.view addConstraint:constraint1];
  2. [self.view addConstraint:constraint2];
  3. [self.view addConstraints:@[constraint3, constraint4]];

4.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @implementation TRViewController
  3. - (void)viewDidLoad
  4. {
  5. [super viewDidLoad];
  6.     UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
  7. button.backgroundColor = [UIColor lightGrayColor];
  8. [button setTitle:@"我是按钮" forState:UIControlStateNormal];
  9. [self.view addSubview:button];
  10. //关闭Autoresizing的翻译功能(将Autoresizing的默认值自动翻译成约束)
  11. button.translatesAutoresizingMaskIntoConstraints = NO;
  12. //创建约束
  13. //距离右边20点:button.right = self.view.right * 1.0 + (-20);
  14. NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20];
  15. //距离上边20点:button.top = self.view.top * 0.0 + 20;
  16. NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:0.0 constant:20];
  17. //固定宽度100
  18. NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0.0 constant:100];
  19. //固定高度40
  20. NSLayoutConstraint *constraint4 = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0 constant:40];
  21. //加入到父视图中
  22. [self.view addConstraint:constraint1];
  23. [self.view addConstraint:constraint2];
  24. [self.view addConstraints:@[constraint3, constraint4]];
  25. }
  26. @end
 

5 使用VFL创建多个约束

5.1 问题

由上一个案例可以看出,逐个创建约束对象会使代码非常的繁琐,IOS提供了一种更简便的方式VFL,即Visual Format Language可视格式化语言帮助我们进行代码创建约束对象,本案例将学习如何使用VFL创建约束对象,如图-24、图-25所示:

图-24

图-25

5.2 方案

首先同样的创建一个SingleViewApplication项目,在TRViewController.m文件的viewDidLoad方法中创建三个UIButton控件button1、button1和button3,设置相关属性,并将按钮添加到父视图中。

然后确认Use AutoLayout功能被打开,同样的在viewDidLoad方法中用代码将按钮的Autoresizing的翻译功能关闭,如果不将其关闭自动布局会自动将Autoresizing功能翻译成约束,造成约束冲突。

再在viewDidLoad方法中通过VFL和工厂方法constraintsWithVisualFormat: options: metrics: views:给每一个button对象创建一组约束对象。

最后将约束对象添加到父视图中。

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建项目,添加按钮控件

首先创建一个SingleViewApplication项目。在TRViewController.m文件的viewDidLoad方法中创建三个Button控件,并将其添加到父视图中,这里需要注意自动布局功能开启时,在viewDidLoad方法中设置控件的frame属性无效,frame是根据自动布局设置自动计算出来的,代码如下所示:

 
  1. UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
  2. button1.backgroundColor = [UIColor lightGrayColor];
  3. [button1 setTitle:@"Button1" forState:UIControlStateNormal];
  4. [self.view addSubview:button1];
  5. UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
  6. button2.backgroundColor = [UIColor lightGrayColor];
  7. [button2 setTitle:@"Button2" forState:UIControlStateNormal];
  8. [self.view addSubview:button2];
  9. UIButton *button3 = [UIButton buttonWithType:UIButtonTypeSystem];
  10. button3.backgroundColor = [UIColor lightGrayColor];
  11. [button3 setTitle:@"Button3" forState:UIControlStateNormal];
  12. [self.view addSubview:button3];

然后在检查器中确认Use AutoLayout功能被打开。在viewDidLoad方法中用代码将按钮的Autoresizing的翻译功能关闭,即将button1、button2和button3的translatesAutoresizingMaskIntoConstraints属性设置为NO。如果不将其关闭自动布局会自动将Autoresizing功能翻译成约束,造成约束冲突,代码所示:

 
  1. button1.translatesAutoresizingMaskIntoConstraints = NO;
  2. button2.translatesAutoresizingMaskIntoConstraints = NO;
  3. button3.translatesAutoresizingMaskIntoConstraints = NO;

步骤二:使用VFL创建约束

通过VFL和工厂方法constraintsWithVisualFormat: options: metrics: views:给每一个button对象创建一组约束对象,先给三个按钮创建水平约束,代码如下所示:

 
  1. //创建VFL字符串
  2. NSString *VFLString = @"|-20-[b1]-10-[b2(==b1)]-10-[b3(==b2)]-20-|";
  3. //根据VFL创建一组约束对象
  4. NSArray *constraits = [NSLayoutConstraint constraintsWithVisualFormat:VFLString options:NSLayoutFormatAlignAllCenterY metrics:nil views:@{@"b1":button1, @"b2":button2, @"b3":button3}];
  5. //将约束添加到父视图中
  6. [self.view addConstraints:constraits];

然后再创建垂直约束,代码如下所示:

 
  1. //创建VFL字符串,V表示垂直约束
  2. VFLString = @"V:|-20-[b1]";
  3. //根据VFL字符串创建约束对象
  4. constraits = [NSLayoutConstraint constraintsWithVisualFormat:VFLString options:0 metrics:nil views:@{@"b1":button1}];
  5. //将约束对象添加到父视图中
  6. [self.view addConstraints:constraits];

5.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @implementation TRViewController
  3. - (void)viewDidLoad
  4. {
  5. [super viewDidLoad];
  6.     UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
  7. button1.backgroundColor = [UIColor lightGrayColor];
  8. [button1 setTitle:@"Button1" forState:UIControlStateNormal];
  9. [self.view addSubview:button1];
  10. UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
  11. button2.backgroundColor = [UIColor lightGrayColor];
  12. [button2 setTitle:@"Button2" forState:UIControlStateNormal];
  13. [self.view addSubview:button2];
  14. UIButton *button3 = [UIButton buttonWithType:UIButtonTypeSystem];
  15. button3.backgroundColor = [UIColor lightGrayColor];
  16. [button3 setTitle:@"Button3" forState:UIControlStateNormal];
  17. [self.view addSubview:button3];
  18. //1. 关闭Autoresizing的自动翻译
  19. button1.translatesAutoresizingMaskIntoConstraints = NO;
  20. button2.translatesAutoresizingMaskIntoConstraints = NO;
  21. button3.translatesAutoresizingMaskIntoConstraints = NO;
  22. //2. 创建约束
  23. NSString *VFLString = @"|-20-[b1]-10-[b2(==b1)]-10-[b3(==b2)]-20-|";
  24. NSArray *constraits = [NSLayoutConstraint constraintsWithVisualFormat:VFLString options:NSLayoutFormatAlignAllCenterY metrics:nil views:@{@"b1":button1, @"b2":button2, @"b3":button3}];
  25. //3. 将约束加入到父视图
  26. [self.view addConstraints:constraits];
  27. VFLString = @"V:|-20-[b1]";
  28. constraits = [NSLayoutConstraint constraintsWithVisualFormat:VFLString options:0 metrics:nil views:@{@"b1":button1}];
  29. [self.view addConstraints:constraits];
  30. }
  31. @end
posted on 2015-12-15 20:43  A蜗牛为梦想而生A  阅读(154)  评论(0编辑  收藏  举报