zoukankan      html  css  js  c++  java
  • Autoresizing和AutoLayout

    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
  • 相关阅读:
    使用VS2005搭建典型高效的SharePoint开发环境,提高生产效率,包含远程调试,自动部署 无为而为
    该死的Windows 2003 Server DMA设置,然我刻录DVD这么慢,终于找到办法了 无为而为
    听说Team Foundation Server 繁體中文版於 2006.04.28 RTM ,不知道微软中国的工作做得如何? 无为而为
    [软件开发过程]反模式:简单的部分留在需求人员的脑海中,只描述最复杂的部分给我们听 无为而为
    软件过程改进(SPI)常见反模式:第22条军规 无为而为
    在WebPart中上传图片到SharePoint图片库,读取Exif信息到图片的自定义属性 无为而为
    SQL Server 2005 Service Pack 1正式发布了,我想起,有人说,微软的软件至少要等到出了SP1才能用,那么现在可以用SQL2005了 无为而为
    可以下载Microsoft ISA Server 2006 试用版了,网管需要关注 无为而为
    超女带给我们什么? 无为而为
    Asp.net Url改写方法——采用HttpModules(转)
  • 原文地址:https://www.cnblogs.com/52190112cn/p/5049456.html
Copyright © 2011-2022 走看看