• iOS,自动布局autoresizing和auto layout,VFL语言


    1.使用autoresizing

    2.使用autolayout

    3.VFL语言(Visual Format Language:可视化格式语言)

    使用autoresizing

    点击xib文件,去掉使用autolayout(autolayout和autoresizing只能使用一个)
      iOS,自动布局autoresizing和autolayout - Vie - Vie
    如图中所示
       1.代表视图距离父容器顶部距离固定
       2.代表视图距离父容器左边距离固定
       3.代表视图距离父容器底部距离固定
       4.代表视图距离父容器右边距离固定
       5.中间水平线表示视图随着父容器变宽而变宽(按比例)
       6.中间垂直线表示视图随着父容器变高而变高(按比例)
     
    autoresizing的局限性就是只能表现父视图与子视图的关系,而无法表达兄弟视图之间的关系。在处理复杂布局上比较无力
     

    使用autolayout

     autolayout的2个核心概念: 参照、约束

    注意:

    如果使用autolayout来约束控件,那frame就失效了,官方也不建议我们再设置frame了  。

            如果利用autolayout约束一个控件,和我们以前使用frame约束控件一样,必须设置宽度/高度/X/Y,如果缺少一个约束就会报错,报错有可能会引发一些未知的bug 

            如果有红色错误:代表缺少约束,或者约束有冲突(约束可以重复添加 )

            如果有黄色警告:代表当前的位置大小和约束的位置大小不一样

           在使用autolayout时,最好给每个控件起一个名称,方便阅读

          在使用autolayout让某个控件相对于另一个控件约束,一定要在另一个控件周围

        iOS8,默认情况下,左右两边会留出一段距离

       xib编辑页面autolayout相关约束选项

    iOS,自动布局autoresizing和autolayout - Vie - Vie

     

    iOS,自动布局autoresizing和autolayout - Vie - Vie

    设置好约束后在各个尺寸,横竖屏下查看效果

    iOS,自动布局autoresizing和autolayout - Vie - Vie
    Xcode8中查看
     
     
     

    下面设置红色视图宽度为蓝色的一半。

    先约束红色和蓝色等宽,然后选中约束,改变下图所写值(Multiplier乘数),然后红色就为蓝色宽的一半;
    (注:在水平居中、垂直居中等约束方式上也可以进行类似的约束操作)
    Priority优先级一般不用改(优先级最大为1000,优先级越高的约束越先被满足)
    iOS,自动布局autoresizing和autolayout - Vie - Vie
     

    同理宽度也可以采取相同方法


    代码实现Autolayout(太麻烦,开发中不介意这样用)
    代码实现autolayout的注意点
           *要先禁止autoresizing功能,设置view的下面属性为NO;
     view.translatesAutoresizingMaskIntoConstraints=NO;
           *添加约束之前,一定要保证相关控件都已经在各自的父控件上。(先add控件,再添加约束)
           *不用再给view设置frame
    代码实现autolayout的步奏
    *利用NSLayoutConstraint类创建具体的约束对象。
    *添加约束对象到相应的view上
    -(void)addCOnstraint:(NSLayoutConstraint *)constraint;
    -(void)addConstraints:(NSArray *)constraints;

      在添加目标view约束时会遵循以下规则。(通过代码添加约束时参照该规则)

          1)对于两个同层级view之间的约束关系,添加到它们的父view上

          2)对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上(父view不同,继续找父view的父view...)

          3)对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上

    示例:
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //添加2个控件到父控件上
        //添加蓝色view
        UIView *blueView=[[UIView alloc] init];
        blueView.backgroundColor=[UIColor blueColor];
        //禁用autoresizing
        blueView.translatesAutoresizingMaskIntoConstraints=NO;
        [self.view addSubview:blueView];
    
        //添加红色view
        UIView *redView=[[UIView alloc] init];
        redView.backgroundColor=[UIColor redColor];
        //禁用autoresizing
        redView.translatesAutoresizingMaskIntoConstraints=NO;
        [self.view addSubview:redView];
        
        //添加约束
        //添加蓝色View距离父控件左边的距离固定为20  x
        /*
         item == first item  需要设置约束的控件
         attribute == 需要设置的约束
         relatedBy == relation 等于
         toItem == second item 被参照的控件
         attribute == 需要设置的约束
         multiplier == multiplier 乘以
         constant == constant 加上
         */
        //蓝色view的左边等于父控件的左边乘以1加20
        NSLayoutConstraint *leftCos=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.viewattribute:NSLayoutAttributeLeft multiplier:1.0f constant:20];
        [self.view addConstraint:leftCos];
        //添加蓝色View距离父控件右边的距离固定为20  宽度
        NSLayoutConstraint *rightCos=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.viewattribute:NSLayoutAttributeRight multiplier:1.0f constant:-20];
        [self.view addConstraint:rightCos];
        //添加蓝色View距离父控件顶部边的距离固定为20 y
         NSLayoutConstraint *topCos=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.viewattribute:NSLayoutAttributeTop multiplier:1.0f constant:20];
        [self.view addConstraint:topCos];
        //添加蓝色View的高度50                   高度
         NSLayoutConstraint *heightCos=[NSLayoutConstraintconstraintWithItem:blueView attribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqual toItem:nilattribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:50];
        [blueView addConstraint:heightCos];
    
        
    
        //设置红色约束
        //红色高度和蓝色一样  height
        NSLayoutConstraint *redHeightCos=[NSLayoutConstraintconstraintWithItem:redView attribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeightmultiplier:1.0f constant:0];
        [self.view addConstraint:redHeightCos];
        //红色的右边和蓝色右边对齐  x
        NSLayoutConstraint *redRightCos=[NSLayoutConstraintconstraintWithItem:redView attribute:NSLayoutAttributeRightrelatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeRightmultiplier:1.0f constant:0];
    
        [self.view addConstraint:redRightCos];
        //红色的顶部和蓝色底部距离固定20   y
        NSLayoutConstraint *redTopCos=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:20];
    
        [self.view addConstraint:redTopCos];
    
        //红色宽度等于蓝色宽度一半
    
        NSLayoutConstraint *redWidthCos=[NSLayoutConstraintconstraintWithItem:redView attribute:NSLayoutAttributeWidthrelatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidthmultiplier:0.5f constant:0];
        [self.view addConstraint:redWidthCos];
    }

    iOS,自动布局autoresizing和autolayout - Vie - VieiOS,自动布局autoresizing和autolayout - Vie - Vie

     

    VFL语言(Visual Format Language:可视化格式语言)

    VFL语言是苹果公司为了简化Autolayout的编码而推出的抽象语言

    VFL示例
    • H:[cancelButton(72)]-12-[acceptButton(50)]
    • canelButton宽72,acceptButton宽50,它们之间水平间距12
    • H:[wideView(>=60@700)]
    • wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)
    • V:[redBox]-[yellowBox(==redBox)]
    • 竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
    • H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
    • 水平方向上,Find距离父view左边缘默认间隔宽度10,之后是FindNext距离Find间隔默认宽度0;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
    和上面代码实现Autolayout完成同样的demo效果
    - (void)viewDidLoad {
        [super viewDidLoad];
        //添加2个控件到父控件上
        //添加蓝色view
        UIView *blueView=[[UIView alloc] init];
        blueView.backgroundColor=[UIColor blueColor];
        //禁用autoresizing
        blueView.translatesAutoresizingMaskIntoConstraints=NO;
        [self.view addSubview:blueView];
    
        //添加红色view
        UIView *redView=[[UIView alloc] init];
        redView.backgroundColor=[UIColor redColor];
        //禁用autoresizing
        redView.translatesAutoresizingMaskIntoConstraints=NO;
        [self.view addSubview:redView];
    
        //添加约束
        /*
         VisualFormat:VFL语句
         options:对齐方式
         metrics:VFL语句中用到的变量值
         views:VFL语句中用到的控件
         */
        //blueView水平方向距离两边各20距离,设置了x值和宽度
        NSArray *blueViewHorizontal=[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:0 metrics:nilviews:@{@"blueView":blueView}];
        [self.view addConstraints:blueViewHorizontal];
        //blueView垂直方向距离顶部20距离,高度50 ,blueView底部距离redView为20距离  redView高度==blueView;并且设置红色和蓝色右边对齐
        NSArray *blueViewVertical=[NSLayoutConstraintconstraintsWithVisualFormat:@"V:|-20-[blueView(50)]-20-[redView(==blueView)]"options:NSLayoutFormatAlignAllRight metrics:nilviews:@{@"blueView":blueView,@"redView":redView}];
        [self.view addConstraints:blueViewVertical];
    
        
    
        //注意:在VFL语句中是不支持乘除法,要用autolayout代码实现
    //    NSArray *redViewHorizontal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:[redView(==blueView)]" options:0 metrics:nil views:@{@"blueView":blueView,@"redView":redView}];
    //    [self.view addConstraints:redViewHorizontal];
        NSLayoutConstraint *redViewW=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
        [self.view addConstraint:redViewW];
    }

    //示例:UIScrollView上使用VFL约束,可滚动

    //
    //  ViewController.m
    //  MQTTSDKLearn
    //
    //  Created by Vie on 2017/3/3.
    //  Copyright © 2017年 Vie. All rights reserved.
    //
    
    #import "ViewController.h"
    
    
    @interface ViewController ()
    @property (nonatomic, strong)MQTTSession *mqttSession;
    @property (nonatomic, strong)UIScrollView *scrollView;//滚动视图
    @property (nonatomic, strong)UITextField *userNameField;//账号输入框
    @property (nonatomic, strong)UITextField *passwordField;//密码输入框
    @property (nonatomic, strong)UITextField *ipField;//ip输入框
    @property (nonatomic, strong)UITextField *portField;//端口号输入框
    @property (nonatomic, strong)UIButton *loginBtn;//登陆按钮
    @end
    
    @implementation ViewController
    #pragma mark LazyLoading
    -(UIScrollView *)scrollView{
        if (!_scrollView) {
            _scrollView=[[UIScrollView alloc] init];
            _scrollView.translatesAutoresizingMaskIntoConstraints=false;
            //设置垂直指示滚动标不可见
            _scrollView.showsVerticalScrollIndicator = NO;
        }
        return _scrollView;
    }
    -(UITextField *)userNameField{
        if (!_userNameField) {
            _userNameField=[[UITextField alloc] init];
            _userNameField.translatesAutoresizingMaskIntoConstraints=false;
            _userNameField.layer.borderWidth=1.0;
            _userNameField.layer.borderColor=[UIColor blackColor].CGColor;
            [_userNameField.layer setCornerRadius:5.0f];
            _userNameField.placeholder=@"请输入用户名";
            _userNameField.text=@"admin";
        }
        return _userNameField;
    }
    -(UITextField *)passwordField{
        if (!_passwordField) {
            _passwordField=[[UITextField alloc] init];
            _passwordField.translatesAutoresizingMaskIntoConstraints=false;
            _passwordField.layer.borderWidth=1.0;
            _passwordField.layer.borderColor=[UIColor blackColor].CGColor;
            [_passwordField.layer setCornerRadius:5.0f];
            _passwordField.placeholder=@"请输入密码";
            _passwordField.text=@"admin";
        }
        return _passwordField;
    }
    -(UITextField *)ipField{
        if (!_ipField) {
            _ipField=[[UITextField alloc] init];
            _ipField.translatesAutoresizingMaskIntoConstraints=false;
            _ipField.layer.borderWidth=1.0;
            _ipField.layer.borderColor=[UIColor blackColor].CGColor;
            [_ipField.layer setCornerRadius:5.0f];
            _ipField.placeholder=@"请输入IP地址";
            _ipField.text=@"10.4.145.68";
        }
        return _ipField;
    }
    -(UITextField *)portField{
        if (!_portField) {
            _portField=[[UITextField alloc] init];
            _portField.translatesAutoresizingMaskIntoConstraints=false;
            _portField.layer.borderWidth=1.0;
            _portField.layer.borderColor=[UIColor blackColor].CGColor;
            [_portField.layer setCornerRadius:5.0f];
            _portField.placeholder=@"请输入端口号";
            _portField.text=@"1884";
        }
        return _portField;
    }
    -(UIButton *)loginBtn{
        if (!_loginBtn) {
            _loginBtn=[[UIButton alloc] init];
            _loginBtn.translatesAutoresizingMaskIntoConstraints=false;
            [_loginBtn setTitle:@"登 录 订 阅" forState:UIControlStateNormal];
            [_loginBtn setBackgroundColor:[UIColor colorWithRed:104/255.0 green:200/255.0 blue:250/255.0 alpha:1]];
            [_loginBtn.layer setCornerRadius:8.0f];
            [_loginBtn addTarget:self action:@selector(connectAction:) forControlEvents:UIControlEventTouchUpInside];
        }
        return _loginBtn;
    }
    #pragma  mark viewLoad
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self.view addSubview:self.scrollView];
        [self.scrollView addSubview:self.userNameField];
        [self.scrollView addSubview:self.passwordField];
        [self.scrollView addSubview:self.ipField];
        [self.scrollView addSubview:self.portField];
        [self.scrollView addSubview:self.loginBtn];
        
        [self layoutVFL];
    
    }
    
    -(void)layoutVFL{
        /*最底部或最旁边一个视图要确定与_scrollView的位置关系,这样_scrollView才能确定contenSize是否滑动*/
        /*滚动视图水平约束*/
        NSArray *scrollViewHorizotal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_scrollView]-0-|" options:0 metrics:nil views:@{@"_scrollView":_scrollView}];
        [self.view addConstraints:scrollViewHorizotal];
        /*滚动视图垂直约束*/
        NSArray *scrollViewViertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_scrollView]-0-|" options:0 metrics:nil views:@{@"_scrollView":_scrollView}];
        [self.view addConstraints:scrollViewViertical];
        
        
        
        
        /*用户名宽度约束,_userNameField宽度=_scrollView的1.0倍-60*/
        NSLayoutConstraint *fieldWidth=[NSLayoutConstraint constraintWithItem:_userNameField attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_scrollView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:-60];
        [self.scrollView addConstraint:fieldWidth];
        
        //添加_userNameField距离父控件右边的距离固定为20  宽度
        NSLayoutConstraint *rightCos=[NSLayoutConstraint constraintWithItem:_userNameField attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_scrollView attribute:NSLayoutAttributeRight multiplier:1.0f constant:-30];
        [self.scrollView addConstraint:rightCos];
        
        //_userNameField的左边等于父控件的左边乘以1加20
        NSLayoutConstraint *leftCos=[NSLayoutConstraint constraintWithItem:_userNameField attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_scrollView attribute:NSLayoutAttributeLeft multiplier:1.0f constant:30];
        [self.scrollView addConstraint:leftCos];
    
        /*用户名垂直方向约束*/
        NSArray *userNameFieldViertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[_userNameField(45)]" options:0 metrics:nil views:@{@"_userNameField":_userNameField}];
        [self.scrollView addConstraints:userNameFieldViertical];
       
        
    
        /*密码输入框水平约束*/
        NSArray *passwordFieldHorizotal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[_passwordField(==_userNameField)]" options:0 metrics:nil views:@{@"_passwordField":_passwordField,@"_userNameField":_userNameField}];
        [self.scrollView addConstraints:passwordFieldHorizotal];
        /*密码输入框垂直约束*/
        NSArray *passwordFieldViertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_userNameField]-30-[_passwordField(==_userNameField)]" options:0 metrics:nil views:@{@"_passwordField":_passwordField,@"_userNameField":_userNameField}];
        [self.scrollView addConstraints:passwordFieldViertical];
        
        
        
        /*ip输入框水平约束*/
        NSArray *ipFieldHorizotal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[_ipField(==_passwordField)]" options:0 metrics:nil views:@{@"_passwordField":_passwordField,@"_ipField":_ipField}];
        [self.scrollView addConstraints:ipFieldHorizotal];
        /*ip输入框垂直约束*/
        NSArray *ipFieldViertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_passwordField]-30-[_ipField(==_passwordField)]" options:0 metrics:nil views:@{@"_passwordField":_passwordField,@"_ipField":_ipField}];
        [self.scrollView addConstraints:ipFieldViertical];
        
        /*端口输入框水平约束*/
        NSArray *portFieldHorizotal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[_portField(==_ipField)]" options:0 metrics:nil views:@{@"_ipField":_ipField,@"_portField":_portField}];
        [self.scrollView addConstraints:portFieldHorizotal];
        /*端口输入框垂直约束*/
        NSArray *portFieldViertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_ipField]-30-[_portField(==_ipField)]" options:0 metrics:nil views:@{@"_ipField":_ipField,@"_portField":_portField}];
        [self.scrollView addConstraints:portFieldViertical];
        
        
        /*登录按钮水平约束*/
        NSArray *loginBtnHorizotal=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[_loginBtn(==_portField)]" options:0 metrics:nil views:@{@"_loginBtn":_loginBtn,@"_portField":_portField}];
        [self.scrollView addConstraints:loginBtnHorizotal];
        /*登录按钮垂直约束*/
        NSArray *loginBtnViertical=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_portField]-30-[_loginBtn(==_portField)]-230-|" options:0 metrics:nil views:@{@"_loginBtn":_loginBtn,@"_portField":_portField}];
        [self.scrollView addConstraints:loginBtnViertical];
    }
    
    
    //连接Socket服务
    -(void)connectAction:(UIButton *)sender{
        NSLog(@"连接MQTT服务器登陆验证");
    }
    
    @end
  • 相关阅读:
    [Linux 004]——用户和用户组以及 Linux 权限管理(二)
    [Linux 003]——用户和用户组以及 Linux 权限管理(一)
    [Linux 002]——Linux的常用命令
    [Linux 001]——计算机和操作系统的基础知识
    给 Android 开发者的 RxJava 详解
    Mac OSX系统搭建React natvie for android 开发环境
    Java中的堆和栈的区别
    Nginx配置详解
    在博客园安家了!
    J2SE核心实战开发—— 集合类框架
  • 原文地址:https://www.cnblogs.com/douniwanxia/p/5892764.html
Copyright © 2020-2023  润新知