iOS开发NSLayoutConstraint代码自动布局
1、NSLayoutConstraint简介
适配界面大多用Masonry工具,也是基于NSLayoutConstraint写的!通过使用两个类方法实现自动布局:
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views; +(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
1》使用自动布局之前设置view的自动布局约束为NO(view.translatesAutoresizingMaskIntoConstraints = NO)
2》UIViewController有个方法- (void)updateViewConstraints;
UIView有个方法- (void)updateConstraints;在对应的方法中设置自动布局;
2、如何使用constraintsWithVisualFormat和VFL语言
2.1》constraintsWithVisualFormat方法说明:
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;
方法说明:此方法通过VFL语言进行适配
format:VFL语句字符串形式
opts:枚举参数 NSLayoutFormatOptions
metrics:字典 放置VFL语言用到的参数(例如height)对应key
views:字典 放置VFL语言用到的view对应key
2.2》VFL语言简介
VFL(Visual Format Language)可视化格式语言,是苹果公司为了简化AutoLayout而编码推出的抽象语言。
具体表示方法: 水平方向 H: 垂直方向 V: Views [view] 关系 >=,==,<= SuperView | 空间,间隙- - 优先级 @value
2.3》简单使用
创建一个蓝色view,离父视图上左右距离为20px、高为20:
UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:blueView]; NSArray *arr = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[blueView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(blueView)]; NSArray *arrV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[blueView(==height)]" options:0 metrics:@{@"height":@"20"} views:NSDictionaryOfVariableBindings(blueView)]; [self.view addConstraints:arr]; [self.view addConstraints:arrV];
在蓝色view下方创建一个黄色view,左右距离父视图40px、上边离蓝色view8px、高度为20px:
UIView *yellowView = [[UIView alloc] init]; yellowView.backgroundColor = [UIColor yellowColor]; yellowView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:yellowView]; NSArray *arr2 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-40-[yellowView]-40-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(yellowView)]; NSArray *arr2V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[blueView]-[yellowView(==height)]" options:0 metrics:@{@"height":@"20"} views:NSDictionaryOfVariableBindings(blueView,yellowView)]; [self.view addConstraints:arr2]; [self.view addConstraints:arr2V];
注意:-:在父视图中表示20px,同级视图表示8px;
参数metrics和views要和VFL语言的参数对应,否则会崩溃;
3、如何使用constraintWithItem方法
3.1》constraintWithItem方法说明:
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
view1:设置的视图
attr1:view1设置的属性
relation:视图view1和view2的属性关系
view2:参照视图
attr2:view2设置的属性
multiplier:视图view1指定属性是view2指定属性的多少倍
c:view1指定属性需要添加的浮点数
3.2》简单使用
添加一个view位于父视图中心、宽度相等、高度为父视图一半:
UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:blueView]; NSMutableArray *constraints = [NSMutableArray array]; [constraints addObject:[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]]; [constraints addObject:[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:.5 constant:0.0]]; [constraints addObject:[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]]; [constraints addObject:[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]]; [self.view addConstraints:constraints];
4、NSLayoutRelation、NSLayoutAttribute、NSLayoutFormatOptions枚举说明
4.1》NSLayoutRelation说明:
typedef NS_ENUM(NSInteger, NSLayoutRelation) { NSLayoutRelationLessThanOrEqual = -1, //视图关系小于或等于 NSLayoutRelationEqual = 0,//视图关系等于 NSLayoutRelationGreaterThanOrEqual = 1,//视图关系大于或等于 };
4.2》NSLayoutAttribute说明:
typedef NS_ENUM(NSInteger, NSLayoutAttribute) { NSLayoutAttributeLeft = 1,//视图的左边 NSLayoutAttributeRight,//视图的右边 NSLayoutAttributeTop,//视图的上边 NSLayoutAttributeBottom,//视图的下边 NSLayoutAttributeLeading,//视图的前边 NSLayoutAttributeTrailing,//视图的后边 NSLayoutAttributeWidth,//视图的宽度 NSLayoutAttributeHeight,//视图的高度 NSLayoutAttributeCenterX,//视图中心的X值 NSLayoutAttributeCenterY,//视图中心的Y值 NSLayoutAttributeLastBaseline,//视图的下基准线 NSLayoutAttributeBaseline NS_SWIFT_UNAVAILABLE("Use 'lastBaseline' instead") = NSLayoutAttributeLastBaseline, NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0),//视图的上基准线 NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),//视图的左边距 NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),//视图的右边距 NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0),//视图的上边距 NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),//视图的下边距 NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),//视图的前边距 NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),//视图的后边距 NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),//视图的中心X边距 NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),//视图的中心Y边距 NSLayoutAttributeNotAnAttribute = 0//无属性 };
注意:NSLayoutAttributeLeading和NSLayoutAttributeTrailing表示前、后边,因为中国书写是从左向右。如果从右向左则表示后、前边;
NSLayoutAttributeLastBaseline和NSLayoutAttributeFirstBaseline表示基准线,举例UILabel的上下基准线就是文字的上下边线;
4.3》NSLayoutFormatOptions说明
typedef NS_OPTIONS(NSUInteger, NSLayoutFormatOptions) { NSLayoutFormatAlignAllLeft = (1 << NSLayoutAttributeLeft),//所有视图左边缘对齐。 NSLayoutFormatAlignAllRight = (1 << NSLayoutAttributeRight),//所有视图右边缘对齐 NSLayoutFormatAlignAllTop = (1 << NSLayoutAttributeTop),//所有视图顶部对齐 NSLayoutFormatAlignAllBottom = (1 << NSLayoutAttributeBottom),//所有视图底部对齐 NSLayoutFormatAlignAllLeading = (1 << NSLayoutAttributeLeading),//视图当前区域文字开始的边缘对齐(英文:左边,希伯来语:右边) NSLayoutFormatAlignAllTrailing = (1 << NSLayoutAttributeTrailing),//视图当前区域文字结束的边缘对齐(英文:右边,希伯来语:左边) NSLayoutFormatAlignAllCenterX = (1 << NSLayoutAttributeCenterX),//视图中心点x对齐 NSLayoutFormatAlignAllCenterY = (1 << NSLayoutAttributeCenterY),//视图中心点y对齐 NSLayoutFormatAlignAllLastBaseline = (1 << NSLayoutAttributeLastBaseline),//视图内容底部基线对齐、有文字就是文字底部 NSLayoutFormatAlignAllBaseline NS_SWIFT_UNAVAILABLE("Use 'alignAllLastBaseline' instead") = NSLayoutFormatAlignAllLastBaseline, NSLayoutFormatAlignAllFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0) = (1 << NSLayoutAttributeFirstBaseline),,//视图内容定部基线对齐、有文字就是文字顶部 //根据编辑内容和编写方向方式进行对齐 NSLayoutFormatAlignmentMask = 0xFFFF, NSLayoutFormatDirectionLeadingToTrailing = 0 << 16, // default NSLayoutFormatDirectionLeftToRight = 1 << 16, NSLayoutFormatDirectionRightToLeft = 2 << 16, NSLayoutFormatDirectionMask = 0x3 << 16, NSLayoutFormatSpacingEdgeToEdge API_AVAILABLE(ios(11.0),tvos(11.0)) = 0 << 19, // default NSLayoutFormatSpacingBaselineToBaseline API_AVAILABLE(ios(11.0),tvos(11.0)) = 1 << 19, NSLayoutFormatSpacingMask API_AVAILABLE(ios(11.0),tvos(11.0)) = 0x1 << 19, };