VFL(Visual Format Language)

ps:看这篇小说从前最好先对约束有点了然,即使不打听,可以去看看自家的另一篇小说,苹果原代码完成Autolayout

  • 事先已经为我们不难介绍了用苹果原API完结Autolayout,现在本身来介绍另一种Autolayout的贯彻方式
  • VFL是如哪天候出的我也不记得了哈,它的出生是为了减轻原API带来的繁琐
  • 本身个人觉得VFL其实也没好到哪里去,哈哈,个人愚见啊
  • 好,接下去自己详细的为我们解读那个东东

VFL思想

  • VFL的思索与其他的贯彻形式有所分裂,它越是宏观化,它将封锁分成了两块
    • 水平方向(H:)
    • 垂直方向(V:)
  • 也就是说,大家在开创约束的时候,得把水平与垂直方向的封锁用字符串一并表明出来,而不是一个一个的丰盛

VFL代码解析

  • 本人先来给大家介绍一下VFL的API,它的API短了一些,可是要筹齐参数是件很辛劳的事

/**
 *  VFL创建约束的API
 *
 *  @param format  传入某种格式构成的字符串,用以表达想要添加的约束,如@"H:|-margin-[redView(50)]",水平方向上,redView与父控件左边缘保持“margin”间距,redView的宽为50
 *  @param opts    对齐方式,是个枚举值
 *  @param metrics 一般传入以间距为KEY的字典,如: @{ @"margin":@20},KEY要与format参数里所填写的“margin”相同
 *  @param views   传入约束中提到的View,也是要传入字典,但是KEY一定要和format参数里所填写的View名字相同,如:上面填的是redView,所以KEY是@“redView”
 *
 *  @return 返回约束的数组
 */
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;

//部分NSLayoutFormatOptions的枚举选项
/*
NSLayoutFormatAlignAllLeft = (1 << NSLayoutAttributeLeft),//左边缘对齐
    NSLayoutFormatAlignAllRight = (1 << NSLayoutAttributeRight),//右边缘对齐
    NSLayoutFormatAlignAllTop = (1 << NSLayoutAttributeTop),
    NSLayoutFormatAlignAllBottom = (1 << NSLayoutAttributeBottom),
    NSLayoutFormatAlignAllLeading = (1 << NSLayoutAttributeLeading),//左边缘对齐
    NSLayoutFormatAlignAllTrailing = (1 << NSLayoutAttributeTrailing),//右边缘对齐
    NSLayoutFormatAlignAllCenterX = (1 << NSLayoutAttributeCenterX),//垂直方向中心对齐
    NSLayoutFormatAlignAllCenterY = (1 << NSLayoutAttributeCenterY),//水平方向中心对齐
*/
  • 看完这些API,大家应该明了了,里面最器重的就是format参数,而以此参数的难点在于其书写格式
  • 为了让我们能够读懂这些格式,我现在提议一个急需,并且落成它,让大家收看那么些格式是怎么工作的
  • 明天自我要在界面上添加一个革命方块,高100,宽50,与父视图顶部和左边缘的间距为20
  • 让大家来看望代码怎么落到实处

//先打一些大家熟悉的代码,放松一下心情
//创建View填到父视图
UIView *redView = [[UIView alloc]init];
    redView.backgroundColor = [UIColor redColor];
    redView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:redView];
//接下来开始写API所需要的参数了
//format参数
//Hvfl与Vvfl分别是水平方向与垂直方向的约束,等下之后会有解析
    NSString *Hvfl = @"H:|-margin-[redView(50)]";
    NSString *Vvfl = @"V:|-margin-[redView(100)]";
//设置margin的数值
    NSDictionary *metrics = @{ @"margin":@20};
//把要添加约束的View转成字典
    NSDictionary *views = NSDictionaryOfVariableBindings(redView);//这个方法会自动把传入的参数以字典的形式返回,字典的KEY就是其本身的名字
//如@{@"redView":redView}

//添加对齐方式,
NSLayoutFormatOptions ops = NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllTop;//左边与顶部

//参数已经设置完了,接收返回的数组,用以self.view添加
    NSArray *Hconstraints = [NSLayoutConstraint constraintsWithVisualFormat:Hvfl options:ops metrics:metrics views:views];

    NSArray *Vconstraints = [NSLayoutConstraint constraintsWithVisualFormat:Vvfl options:ops metrics:metrics views:views];
    //self.view分别添加水平与垂直方向的约束
    [self.view addConstraints:Hconstraints];
    [self.view addConstraints:Vconstraints];

效果图

  • 如图,必要已经落到实处了,接下去自己解释一下format这中间竟然的语法
    • 每句前面都要加@”H:”或者@”V:”,分别代表着水平和垂直方向
    • @”|”代表着边界,很形象哈
    • @”-“用来代表间隙,一般以这样的方式出现@”-20-“,那象征20的间隔,也足以填充标识,如@”-margin-“,之后设置替换参数metrics
    • @”[]”中括号里放的就是要加上约束的View,如上边例子的redView,想要设置宽度或者度,就像此[redView(50)],水平方向(H:)填写这几个数字代表的就是宽,垂直方向就是高(V:)

例子

  • 宗旨的用法就是那般,更多的事物要在代码中体会
  • 现在大家来做一个稍微复杂一点的例子,那个事例在自身的,苹果原代码完结Autolayout
    作品里也用过
  • 即便在离开self.view的平底20区间的地点放置多少个方块,红,蓝,黄,分别间隔20,宽高相同,都为50
  • 接下去就用代码说话啊

//translatesAutoresizingMaskIntoConstraints属性设置为NO,防止苹果把默认设置的Autoresizing属性转成Autolayout,造成错误
//依次创建三个View
UIView *redView = [[UIView alloc]init];
    redView.backgroundColor = [UIColor redColor];
    redView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:redView];

    UIView *blueView = [[UIView alloc]init];
    blueView.backgroundColor = [UIColor blueColor];
    blueView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:blueView];

    UIView *yellowView = [[UIView alloc]init];
    yellowView.backgroundColor = [UIColor yellowColor];
    yellowView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:yellowView];
//view添加完了,开始创建约束
//1.创建水平方向约束
    NSString *Hvfl = @"H:|-margin-[redView(50)]-margin-[blueView(==redView)]-margin-[yellowView(==redView)]";
    //大家认真体会一下上面这个字符串
    //如果翻译过来就是,边缘-间距-红色view(宽50)-间距-蓝色View(宽等于红色View的宽)-间距-黄色View(宽等于红色View的宽)
    //设置间距要替换的数值,用字典形式
    NSDictionary *metrics = @{ @"margin":@20};
    //把要添加约束的View都转成字典形式
    NSDictionary *views = NSDictionaryOfVariableBindings(redView,blueView,yellowView);
    //设置对齐方式,顶部与底部都与红色View对齐
    NSLayoutFormatOptions ops = NSLayoutFormatAlignAllTop|NSLayoutFormatAlignAllBottom;
    //创建水平方向约束
    NSArray *Hconstraints = [NSLayoutConstraint constraintsWithVisualFormat:Hvfl options:ops metrics:metrics views:views];
//这里依然要设置红色view的高,因为水平方向的约束没有设置红色View的高,其他View仅仅是与它顶部底部对齐,但是高依然未知
    NSString *Vvfl = @"V:[redView(50)]-margin-|";
    //创建垂直方向约束
    NSArray *Vconstraints = [NSLayoutConstraint constraintsWithVisualFormat:Vvfl options:ops metrics:metrics views:views];
//父控件添加约束
    [self.view addConstraints:Hconstraints];
    [self.view addConstraints:Vconstraints];
  • 末尾效果图:

最后效果图

总结

  • VFL落成Autolayout是有局限性的,那话不是本人说的,是苹果自己说的
  • 它一旦想要设置优先级或者是流传倍数关系,必须得用回原API,也就是自身所谓的苹果原API(实在是不亮堂怎么叫)
  • 那也是为啥我上边的事例没有像从前那么做动画
  • 此处VFL仅供我们探听,我或者期待大家利用Masonry那一个第三方来兑现Autolayout,关于Masonry的解读小说我还没写,我会尽快的,等豪门领悟了Masonry之后,我即使求你们用苹果的点子你们也必将不会用,因为实际是用得很爽哈
  • 好了,那篇小说到此截止,有广大相差的地方,希望我们可以不吝赐教!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图