iOS VFL 语法详细

来源:互联网 发布:中小企业数据统计2017 编辑:程序博客网 时间:2024/04/30 02:49

http://www.jianshu.com/p/757cc57fd9ea

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,造成错误//依次创建三个ViewUIView *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之后,我就算求你们用苹果的方法你们也肯定不会用,因为实在是用得很爽哈
  • 好了,这篇文章到此结束,有很多不足的地方,希望大家能够不吝赐教!


文/哟_Json(简书作者)
原文链接:http://www.jianshu.com/p/757cc57fd9ea
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 二值图像 二值图像连通 ajax时间 ajax获取时间传到后台 ajax获取服务器时间传到后台 submit提交时怎么将提交的时间传入后台 gethostbyname 分节符快捷键 ErrorPage! Reason:*Networkbusy*InvalidURL*Failedto install_flash_player_10_active_x 伊织 伊织调教 起重机司机学习 ssni 输入梯形上底下底高,输出面积 python语言,输入梯形上底下底高输出面积 网易产品 https://www.csdndoc.com/blog/390696 https://www.cocoacontrols.com 风之教堂 黄色网站 AV网站 439973416 فیلترشکن WS_CLIPCHILDREN设置键在哪里 数据结构(严蔚敏李冬梅)课后答案 ipz809 一个字包含的二进制位数 linux面试 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 结构体比较好友中年纪最小的 matlab三维矩阵可视化 使QQ崩溃 scanIP 按照规定,在高速公路上行使的机动车,达到或超出本车道限速的10%则处200元罚款;若达到或超出50% c语言输入三个数字 c语言如何输入三个数求平均值 c语言如何输入三个数求和 C语言为什么只录入了第一个数字 输入多个数字