zoukankan      html  css  js  c++  java
  • Autolayout + VFL(Visual Format Language)

    最近在学习iOS的布局,在storyboard里,确定布局的思路:

    1、确定能确定的;

    2、无法确定的,看看是否可以想办法和其他控件关联起来,再根据关系来确定能确定的位置.

    例子:实现如下图的布局

    过程:

    1、确定能确定的;

    左上角的View,左边和上边距离父view的距离都是0(当然,这里假设了view的宽度和高度都是100)

    设置完成后,点击Add 4 Constraints即可,现在界面如下所示;

    左边View Controller Scene后面有个黄色图标,该图标的意思是警告的意思,是最终的位置和目前位置不匹配,更新一下即可,效果如下:

    其他3个的设置过程大概也是一样,不一一设置了.

    2、无法确定的,看看是否可以想办法和其他控件关联起来,再根据关系来确定能确定的位置.

    例子效果图:

    效果图中的两个view的高度和宽度永远相等(这里我设置高度为50),距离父view左边、右边、下边间距和2个view之间的间距相等.都是30.

    这种效果可以确定的是红色view离父view的左边和底部的位置都是固定的,都为30,设置如:

    这里要注意的是设置底部时要注意距离的是父view还是Bottom Layout Guide了,当然顶部也是需要注意的。(其实就是需要注意参照物)

    在这里,会发现设置完后左上角会有个红色的图标,这说明还有位置没有设置约束或者有约束冲突。

    蓝色view离父view的右边和底部的位置都是固定的,也是30:

    那么现在问题来了,只确定这2个位置,是无法给这两个view来确定最终位置的。

    在这里,由于两个view的宽度都是相等的,而且间距也是固定了,那么是否就可以最终固定下这两个view的位置了呢?

    先选中两个view,然后设置宽度相等:

    接着选中任意一个view,设置间距,这里我选择的是红色的view来设置的

    然后更新下frame即可:

    可以选择选中的view,也可以选择所有的,点击Update Frames后,最终结果如下图:

    以上为在storyboard里使用Autolayout来布局的一些过程,其他的也差不多,就不一一讲述了。

    使用代码的形式:

    在添加时唯一要注意的是添加的目标view要遵循以下规则:

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

     

    • 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上

     

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


    实现Autolayout的步骤
    利用NSLayoutConstraint类创建具体的约束对象
    添加约束对象到相应的view上

    - (void)addConstraint:(NSLayoutConstraint *)constraint;

    - (void)addConstraints:(NSArray *)constraints;

    代码实现Autolayout的注意点
    要先禁止autoresizing功能,设置view的下面属性为NO
    view.translatesAutoresizingMaskIntoConstraints = NO;
     
    添加约束之前,一定要保证相关控件都已经在各自的父控件上
    不用再给view设置frame
     
    一个NSLayoutConstraint对象就代表一个约束
    创建约束对象的常用方法
    1 +(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
    view1 :要约束的控件
    attr1 :约束的类型(做怎样的约束)
    relation :与参照控件之间的关系
    view2 :参照的控件
    attr2 :约束的类型(做怎样的约束)
    multiplier :乘数
    c :常量
    自动布局有个核心公式

    obj1.property1 =(obj2.property2 * multiplier)+ constant value

    上面第二个效果图的代码写法如下:

     1  //添加一个红色view
     2     UIView *redView = [[UIView alloc] init];
     3     redView.backgroundColor = [UIColor redColor];
     4     redView.translatesAutoresizingMaskIntoConstraints = NO;
     5     [self.view addSubview:redView];
     6     
     7     
     8     //添加一个蓝色view
     9     UIView *blueView = [[UIView alloc] init];
    10     blueView.backgroundColor = [UIColor blueColor];
    11     blueView.translatesAutoresizingMaskIntoConstraints = NO;
    12     [self.view addSubview:blueView];
    13     
    14     //给红色view添加约束
    15     NSLayoutConstraint *redLeft = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:30.0];
    16     [self.view addConstraint:redLeft];
    17     
    18     NSLayoutConstraint *redBottom = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-30.0];
    19     [self.view addConstraint:redBottom];
    20     
    21     NSLayoutConstraint *redHeight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0.0 constant:50.0];
    22     [redView addConstraint:redHeight];
    23     
    24     //给蓝色view添加约束
    25     NSLayoutConstraint *blueRight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-30.0];
    26     [self.view addConstraint:blueRight];
    27     
    28     NSLayoutConstraint *blueBottom = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-30.0];
    29     [self.view addConstraint:blueBottom];
    30     
    31     NSLayoutConstraint *blueHeight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0.0 constant:50.0];
    32     [blueView addConstraint:blueHeight];
    33     
    34     NSLayoutConstraint *blueWidth = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0];
    35     [self.view addConstraint:blueWidth];
    36     
    37     NSLayoutConstraint *blueLeft = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeRight multiplier:1.0 constant:30.0];
    38     [self.view addConstraint:blueLeft];

     看完使用代码来自动布局是不是有种坑爹的感觉,好长好臭~~别急,苹果还给我们提供了另外一种方式VFL:

    什么是VFL?
    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左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)

    VFL的使用:

    使用VFL来创建约束数组

    + (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;

    format :VFL语句
    opts :约束类型
    metrics :VFL语句中用到的具体数值
    views :VFL语句中用到的控件
     
    上面第二个效果图的VFL代码的写法如下:
     1     //初始化两个view
     2     UIView *redView = [[UIView alloc] init];
     3     redView.backgroundColor = [UIColor redColor];
     4     redView.translatesAutoresizingMaskIntoConstraints = NO;
     5     [self.view addSubview:redView];
     6     
     7     UIView *blueView = [[UIView alloc] init];
     8     blueView.backgroundColor = [UIColor blueColor];
     9     blueView.translatesAutoresizingMaskIntoConstraints = NO;
    10     [self.view addSubview:blueView];
    11 
    12     //设置水平方向上的约束,代表的意思是blueView离父view左边间距为30,和redView的间距为30,redView和父view的右间距为30,redView的宽度和blueView的宽度相等
    13     NSString *hVFL = @"H:|-30-[blueView]-30-[redView(==blueView)]-30-|";
    14     NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatAlignAllBottom | NSLayoutFormatAlignAllTop metrics:nil views:@{@"blueView":blueView,@"redView":redView}];
    15     [self.view addConstraints:hCons];
    16     
    17     //设置垂直方向上的约束,代表的意思是blueView的高度是50,离父view的底部间距是30
    18     NSString *vVFL = @"V:[blueView(50)]-30-|";//@"V:-30-[blueView(50)]",这里的30代表离父类的顶部间距是30
    19     NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:0 metrics:nil views:@{@"blueView":blueView}];
    20     [self.view addConstraints:vCons];

    还是附上效果图吧:

  • 相关阅读:
    (转)AspNetPager分页控件的使用方法 (1)
    对GridView控件的操作:GridView控件的HyperLinkField超链接数据行
    JS实现在Repeater控件中创建可隐藏区域的代码
    Asp.net弹出窗口大全
    AspNetPager分页控件使用方法 (2)
    解决mapXtreme地图更新闪屏
    绝对路径与相对路径的区别【2】release和debug这两种情况下对本地文件操作不一致的问题
    今天开始添加点文章
    第一篇博客~~
    使用 PIVOT 和 UNPIVOT实现行转列,列转行
  • 原文地址:https://www.cnblogs.com/xiaomoge/p/4279245.html
Copyright © 2011-2022 走看看