其实已经有很多介绍VFL的文章,但在这里我也想记录下自己的理解,给需要的朋友一点帮助,如有错误,欢迎指出。
与VFL很重要的两个很重要的方法是:
1、
/*format: 是VFL字符串。
opts:设置VFL语句中的视图相互间的对齐方式,一般默认传0即可。
metrics:字典。一般是把VFL字符串中涉及到的高度、宽带等数据参数转为字典存到metrics中。在format中,高度、宽度等数据参数就用metrics中的key代替,然后编译器解析时会自动替换metrics中的值value。
views: 字典。把format中所有相关的视图控件放入这个字典。
*/
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
2、
/*
view1:需要被设置的那个控件
attr1:即view1需要被设置的属性
relation:设置的属性关系,共有三种关系可供选择
view2:被view1所参照的对象
attr2:即view2需要被设置的属性,一般与attr1一样
multiplier:比例关系
c:不多解释了。
总之,记住它们的关系一般是:view1.attr1=view2.attr2*multiplier+c
当然此时,relation参数是NSLayoutRelationEqual,也就是相当于“=”。
*/
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
VFL语句的组成:
1、“H"、"V"。其中,H表示这是个水平方向上的约束(默认情况下可以不写);V表示这是个垂直方向上的约束。
2、"|"。表示所设置视图的父视图superview。
3、"[xxview对象名]"。这个括号里面放置你要设置的视图xxview对象。
4、"-"。表示间距。
5、"@"。表示优先级
VFL语句操作注意项:
1、设置约束的控件需要设置translatesAutoresizingMaskIntoConstraints=NO
2、添加约束方法:addConstraints
3、删除约束方法:removeConstraint、removeConstraints
4、修改约束方法:我是先删除某个属性约束,然后再重新设置这个属性约束。不知道还有没其他好的方法,欢迎大家提供、分享,一起进步
VFL语句实例:
(代码实现中包括:VFL实现的动态布局,通过点击按钮实现按钮以及其父视图的高度动态变化,以及下面的UIScrollView随之变化,还有UILable内容的高度动态适应)
#import
@interface limit3ViewController :UIViewController
@end
#import "limit3ViewController.h"
@interface limit3ViewController ()
{
BOOL isSelect;
NSLayoutConstraint * constr1;
NSLayoutConstraint * contr2;
UIView * clickView;
UIScrollView * scrollV;
}
@end
@implementation limit3ViewController
- (void)viewDidLoad {
[superviewDidLoad];
isSelect=NO;
clickView=[UIViewnew];
clickView.backgroundColor=[UIColorcyanColor];
clickView.translatesAutoresizingMaskIntoConstraints=NO;//用vfl布局时,此属性要设置为NO
[self.viewaddSubview:clickView];
UIButton * clickBtn=[UIButtonbuttonWithType:UIButtonTypeCustom];
clickBtn.backgroundColor=[UIColororangeColor];
[clickBtn setTitle:@"点击"forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColorblackColor] forState:UIControlStateNormal];
clickBtn.translatesAutoresizingMaskIntoConstraints=NO;//用vfl布局时,此属性要设置为NO
[clickBtn addTarget:selfaction:@selector(toExpandV:)forControlEvents:UIControlEventTouchUpInside];
[clickViewaddSubview:clickBtn];
//H:表示水平方向布局,v:表示垂直方向布局
[self.viewaddConstraints:[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|-10-[clickView]-10-|"options:0metrics:nilviews:NSDictionaryOfVariableBindings(clickView)]];
[clickViewaddConstraints:[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|-30-[clickBtn]-30-|"options:0metrics:nilviews:NSDictionaryOfVariableBindings(clickBtn)]];
[clickViewaddConstraints:[NSLayoutConstraintconstraintsWithVisualFormat:@"V:|-10-[clickBtn]"options:0metrics:nilviews:NSDictionaryOfVariableBindings(clickBtn)]];
//上面的语句与下面的这句结合,可以确定clickBtn的高度比例情况。当然如果你不需要按比例变化clickBtn的高度,也可以不用设置下面这句了,直接用上的VFL布局也OK。
constr1=[NSLayoutConstraintconstraintWithItem:clickBtn attribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:clickViewattribute:NSLayoutAttributeHeightmultiplier:0.5constant:0];
constr1.active =YES;//激活
scrollV=[UIScrollViewnew];
scrollV.translatesAutoresizingMaskIntoConstraints=NO;//用vfl布局时,此属性要设置为NO
scrollV.showsHorizontalScrollIndicator=NO;
[self.viewaddSubview:scrollV];
[self.viewaddConstraints:[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|-10-[scrollV]-10-|"options:0metrics:nilviews:NSDictionaryOfVariableBindings(scrollV)]];
[self.viewaddConstraints:[NSLayoutConstraintconstraintsWithVisualFormat:@"V:|-74-[clickView]-10-[scrollV]-10-|"options:0metrics:nilviews:NSDictionaryOfVariableBindings(scrollV,clickView)]];
contr2=[NSLayoutConstraintconstraintWithItem:clickViewattribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:self.viewattribute:NSLayoutAttributeHeightmultiplier:0.2constant:0];
contr2.active=YES;//激活,也可以这样写[NSLayoutConstraint activateConstraints:contr2];
UILabel* desLabel = [UILabelnew];
desLabel.translatesAutoresizingMaskIntoConstraints =NO;//用vfl布局时,此属性要设置为NO
desLabel.text =@"燕子去了,有再来的时候;杨柳枯了,有再青的时候;桃花谢了,有再开的时候。但是,聪明的,你告诉我,我们的日子为什么一去不复返呢? ——是有人偷了他们罢:那是谁?又藏在何处呢?是他们自己逃走了:现在又到了哪里呢?我不知道他们给了我多少日子;但我的手确乎是渐渐空虚了。在默默里算着,八千多日子已经从我手中溜去;象针尖上一滴水滴在大海里,我的日子滴在时间的流里,没有声音也没有影子。我不禁头涔涔而泪潸潸了。去的尽管去了,来的尽管来着,去来的中间,又怎样的匆匆呢?早上我起来的时候,小屋里射进两三方斜斜的太阳。太阳他有脚啊,轻轻悄悄地挪移了;我也茫茫然跟着旋转。于是——洗手的时候,日子从水盆里过去;吃饭的时候,日子从饭碗里过去;默默时,便从凝然的双眼前过去。我觉察他去的匆匆了,伸出手遮挽时,他又从遮挽着的手边过去,天黑时,我躺在床上,他便伶伶俐俐地从我身边垮过,从我脚边飞去了。等我睁开眼和太阳再见,这算又溜走了一日。我掩着面叹息。但是新来的日子的影儿又开始在叹息里闪过了。在逃去如飞的日子里,在千门万户的世界里的我能做些什么呢?只有徘徊罢了,只有匆匆罢了;在八千多日的匆匆里,除徘徊外,又剩些什么呢?过去的日子如轻烟却被微风吹散了,如薄雾,被初阳蒸融了;我留着些什么痕迹呢?我何曾留着象游丝样的痕迹呢?我赤裸裸来到这世界,转眼间也将赤裸裸地回去罢?但不能平的,为什么偏要白白走这一遭啊?你聪明的,告诉我,我们的日子为什么一去不复返呢?";//此时
desLabel.numberOfLines =0;//此时设置为0,会自动适配UITable高度
desLabel.lineBreakMode=NSLineBreakByCharWrapping;
desLabel.backgroundColor = [UIColorlightGrayColor];
[scrollVaddSubview:desLabel];
[scrollVaddConstraints:[NSLayoutConstraintconstraintsWithVisualFormat:@"V:|-[desLabel]-|"options:0metrics:nilviews:NSDictionaryOfVariableBindings(desLabel)]];
[scrollVaddConstraints:[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|-[desLabel(==scrollV)]-|"options:0metrics:nilviews:NSDictionaryOfVariableBindings(desLabel,scrollV)]];
}
-(void)toExpandV:(UIButton *)btn
{
isSelect=!isSelect;
if(isSelect){
//更新约束
//以防约束冲突,先删除clickView高度的约束,再添加新的约束,使其高度变小。此时,下面的scrollView自动随其变化
[self.viewremoveConstraint:contr2];
contr2=[NSLayoutConstraintconstraintWithItem:clickViewattribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:self.viewattribute:NSLayoutAttributeHeightmultiplier:0.15constant:0];
contr2.active=YES;
[self.viewlayoutIfNeeded];//更新self.view上的约束
//以防约束冲突,先删除设置btn高度的约束,再添加新的约束
[clickViewremoveConstraint:constr1];
constr1=[NSLayoutConstraintconstraintWithItem:btn attribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:clickViewattribute:NSLayoutAttributeHeightmultiplier:0.2constant:0];
constr1.active =YES;
//[self updateViewConstraints];
[clickViewlayoutIfNeeded];//更新clickView上的约束
}else{
//更新约束
//以防约束冲突,先删除clickView高度的约束,再添加新的约束,恢复原来的高度。此时,下面的scrollView自动随其变化
[self.viewremoveConstraint:contr2];
contr2=[NSLayoutConstraintconstraintWithItem:clickViewattribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:self.viewattribute:NSLayoutAttributeHeightmultiplier:0.2constant:0];
contr2.active=YES;
[self.viewlayoutIfNeeded];
//以防约束冲突,先删除设置btn高度的约束,再添加新的约束
[clickViewremoveConstraint:constr1];
constr1=[NSLayoutConstraintconstraintWithItem:btn attribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:clickViewattribute:NSLayoutAttributeHeightmultiplier:0.5constant:0];
constr1.active =YES;
[clickViewlayoutIfNeeded];
}
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end