AutoLayout:
two of the most important concepts:
约束
: Constraints on the position and size of the control
参照
: The constraint that is set on the control is relative to which view
the core calculation formula of automatic layout:
obj1.property1 =(obj2.property2 * multiplier)+ constant value
Explanation: The property1 attribute of obj1 equals the Property2 attribute of obj2 multiplied by multiplier (coefficient) plus constant (constant);
Precedence of Constraints:
The attribute of the constraint represents the precedence of the priority
constraint, and the value interval is [0,1000], which defaults to 1000. priority
the higher the value, the higher the priority, and the first execution. A constraint with a low priority is only executed if the constraint with the higher precedence is invalidated.
Warnings and Errors:
When you use storyboard and xib to set constraints, the constraints may turn yellow or red. When such a situation occurs, there is a problem with the constraints set.
- If the constraint is yellow, this is just a warning that the frame of the control does not match the constraint set, and updating the frame or updating the constraint can be resolved.
- If the constraint is red, this represents an error, the constraint setting is not complete, or there is a conflict between two constraints, and the red error message disappears only if the constraint is set intact and there is no conflict.
3 rules for adding constraints:
- For the constraint relationships between the two same-level view, they should be added to their parent view.
- For the constraint relationships between two different levels of view, they should be added to their nearest common parent view.
- For a hierarchical relationship between the two view constraints, added to the higher level of the parent view
Code Implementation AutoLayout:
Code implementation AutoLayout need to be aware of:
- The autoresizing feature must be disabled first, and the following properties of the view are set
NO
:
view.translatesAutoresizingMaskIntoConstraints = NO;
- Before adding constraints, make sure that the controls are already added to the respective parent control.
- No need to set frame for view
Use
NSLayoutConstraint
class to create a concrete constraint object
To add a constraint to the corresponding view:
- (void)addConstraint:(NSLayoutConstraint *)constraint;- (void)addConstraints:(NSArray *)constraints;
Nslayoutconstraint:
An NSLayoutConstraint
object represents a constraint that can be modified by modifying NSLayoutConstraint
the properties of the object.
Common ways to create constraint objects:
/** * 添加一个约束,其实就是根据公式来计算约束 * obj1.property1 =(obj2.property2 * multiplier)+ constant value * @param view1 需要添加约束的View * @param attr1 需要添加的约束(左边、右边、长宽还是。。。) * @param relation 约束关系(大于、等于还是小于) * @param view2 参照View(约束是相对于哪个View而言) * @param attr2 参照View的哪一个参数(左边、右边、长宽还是。。。) * @param multiplier 系数 * @param c 常量值 * * @return 返回一个创建好的约束 */+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
Example:
UIView *blueview = [[UIView alloc] Init];blueview.backgroundcolor = [Uicolor Bluecolor]; [Self.view addsubview:blueview];//off autoresizingblueview.translatesautoresizingmaskintoconstraints = NO;// Create left constraint nslayoutconstraint *LEFTLC = [Nslayoutconstraint constraintwithitem:blueview attribute:nslayoutattributeleft Relatedby:nslayoutrelationequal ToItem:self.view attribute:nslayoutattributeleft multiplier:1.0 constant:20]; [Self.view addconstraint:leftlc];//Create right constraint nslayoutconstraint *RIGHTLC = [Nslayoutconstraint constraintWithItem: Blueview attribute:nslayoutattributeright relatedby:nslayoutrelationequal toItem:self.view attribute: Nslayoutattributeright multiplier:1.0 constant:-20]; [Self.view addconstraint:rightlc];//creates a bottom constraint nslayoutconstraint *BOTTOMLC = [Nslayoutconstraint constraintWithItem: Blueview attribute:nslayoutattributebottom relatedby:nslayoutrelationequal toItem:self.view attribute: Nslayoutattributebottom multiplier:1.0 constant:-20]; [Self.view addconstraint:bottomlc];//Create height constraint NSLAYOUTCOnstraint *HEIGHTLC = [Nslayoutconstraint constraintwithitem:blueview attribute:nslayoutattributeheight relatedBy: Nslayoutrelationequal toitem:nil attribute:nslayoutattributenotanattribute multiplier:0.0 constant:50]; [Blueview ADDCONSTRAINT:HEIGHTLC];
:
To add a constraint using the VFL statement:
Use the VFL to create an array of constraints:
/*** 使用VFL语句来创建约束数组** @param format VFL语句* @param opts 约束类型* @param metrics VFL语句中用到的具体数值* @param views VFL语句中用到的控件** @return 返回创建好的约束数组*/+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;
VFN Statement Example:
H:[cancelButton(72)]-12-[acceptButton(50)]canelButton宽72,acceptButton宽50,它们之间间距12H:[wideView(>[email protected])]wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)V:[redBox][yellowBox(==redBox)]竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBoxH:|-10-[Find]-[FindNext]-[FindField(>=20)]-|水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
VFN code Example:
Create Blue view UIView *blueview = [[UIView alloc] init]; Blueview.backgroundcolor = [Uicolor Bluecolor]; Blueview.translatesautoresizingmaskintoconstraints = NO; [Self.view Addsubview:blueview]; Create red view UIView *redview = [[UIView alloc] init]; Redview.backgroundcolor = [Uicolor Redcolor]; Redview.translatesautoresizingmaskintoconstraints = NO; [Self.view Addsubview:redview]; The VFL creates a constraint//horizontal direction NSString *vfl_h = @ "H:|-space-[blueview]-space-[redview (==blueview)]-space-|"; Nsdictionary *metrics = @{@ "Space": @30,}; Nsdictionary *views = @{//@ "Blueview": Blueview,//@ "Redview": Redview//}; Nsdictionary *views = nsdictionaryofvariablebindings (Blueview,redview); Nsarray *arrayh = [Nslayoutconstraint constraintswithvisualformat:vfl_h options:nslayoutformatalignalltop metrics: MetRics Views:views]; [Self.view Addconstraints:arrayh]; Vertical direction NSString *vfl_v = @ "V:[blueview (]-space-|)"; Nsarray *arrayv = [nslayoutconstraint constraintswithvisualformat:vfl_v options:kniloptions metrics:metrics Views: views]; [Self.view ADDCONSTRAINTS:ARRAYV]; Add a red view constraint//Add height constraint nslayoutconstraint *redv_height = [Nslayoutconstraint constraintwithitem:redview attribute: Nslayoutattributeheight relatedby:nslayoutrelationequal Toitem:blueview Attribute:nslayoutattributeheight multiplier:1.0 constant:0]; [Self.view Addconstraint:redv_height];
:
What is the VFL language
The VFL (visual format Language), "Visual formatting language".
The VFL is an abstract language that Apple has introduced to simplify AutoLayout coding.
Syntax description
H:[cancelButton(72)]-12-[acceptButton(50)]cancelButton宽72,acceptButton宽50,它们之间间距12H:[wideView(>[email protected])]wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束条件越先被满足)V:[redBox][yellowBox(==redBox)]垂直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBoxH:|-10-[Find]-[FindNext]-[FindField(>=20)]-|水平方向上,Find距离父view左边缘间隔10,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边边缘的间距都是默认宽度。(竖线“|”表示superview的边缘)。
How to use
使用VFL来创建约束数组+(NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;format:VFL语句opts:约束类型metrics:VFL语句中用到的具体数值views:VFL语句中用到的控件创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义NSDictionaryOfVariableBindings(...)
Example Show
As follows:
Implementation code
-(void) horizontallayout{//1. Add two controls UIView *blueview = [[UIView alloc] init]; Blueview.backgroundcolor = [Uicolor Bluecolor]; Blueview.translatesautoresizingmaskintoconstraints = NO; [Self.view Addsubview:blueview]; UIView *redview = [[UIView alloc] init]; Redview.backgroundcolor = [Uicolor Redcolor]; Redview.translatesautoresizingmaskintoconstraints = NO; [Self.view Addsubview:redview]; 2. Add constraint//2.1 horizontal direction constraint nsstring *HVFL = @ "H:|-30-[blueview]-30-[redview (==blueview)]-30-|"; Nsarray *hcons = [Nslayoutconstraint CONSTRAINTSWITHVISUALFORMAT:HVFL options:nslayoutformatalignallbottom | Nslayoutformatalignalltop metrics:nil views:@{@ "Blueview": Blueview, @ "Redview": Redview}]; [Self.view addconstraints:hcons]; 2.2 Constraints of the vertical direction nsstring *VVFL = @ "V:[blueview (50)]-30-|"; Nsarray *vcons = [nslayoutconstraint constraintswithvisualformat:vvfl options:0 metrics:nil views:@{@ "BlueView": Blueview}]; [Self.view addconstraints:vcons];} -(void) Verticallayout{//1. Add two controls UIView *blueview = [[UIView alloc] init]; Blueview.backgroundcolor = [Uicolor Bluecolor]; Blueview.translatesautoresizingmaskintoconstraints = NO; [Self.view Addsubview:blueview]; UIView *redview = [[UIView alloc] init]; Redview.backgroundcolor = [Uicolor Redcolor]; Redview.translatesautoresizingmaskintoconstraints = NO; [Self.view Addsubview:redview]; 2. Add constraint//2.1 horizontal direction constraint nsstring *HVFL = @ "h:|-30-[blueview]-30-|"; Nsarray *hcons = [nslayoutconstraint constraintswithvisualformat:hvfl options:0 metrics:nil views:@{@ "BlueView": Blueview}]; [Self.view addconstraints:hcons]; 2.2 Vertical constraint NSString *VVFL = @ "V:|-30-[blueview (]-30-[redview (==blueview)]"; Nsarray *vcons = [Nslayoutconstraint CONSTRAINTSWITHVISUALFORMAT:VVFL options:nslayoutformatalignallright metrics: Nil views:@{@ "Blueview": Blueview, @ "Redview": Redview}]; [Self.view addconstraints:vcons]; Nslayoutconstraint *redleftcon = [Nslayoutconstraint constrainTwithitem:redview attribute:nslayoutattributeleft relatedby:nslayoutrelationequal toItem:blueView attribute: Nslayoutattributecenterx multiplier:1.0 constant:0]; [Self.view Addconstraint:redleftcon];}
Summary
Finally, a summary of the format string is presented:
function |
An expression |
Horizontal direction |
H: |
Vertical direction |
V: |
Views |
[View] |
Superview |
Vertical bar Symbol |
Relationship |
>=,==,<= |
Space, Gap |
- |
Priority level |
@value |
use of Masonry:
Masonry is currently the most popular AutoLayout third-party framework, allowing you to write AutoLayout with simple code, eliminating the official complexity of Apple's AutoLayout code and greatly improving development efficiency.
mas_equalTo
And
equalTo
:
By default mas_equalTo
, there are auto-wrapping functions, such as automatically 20
wrapping as @20
. equalTo
There is no automatic packing function.
If you add the following macro, then mas_equalTo
equalTo
there is no difference:
#define MAS_SHORTHAND_GLOBALS// 注意:这个宏一定要添加到#import "Masonry.h"前面
mas_width
And
width
:
By default
width
is make
a property of an object that is used to add a width constraint, which means that the width is constrained. mas_width
is a property value that is used as equalTo
the parameter that represents the width property of a control.
If you add the following macro, mas_width
you can also write width
:
#define MAS_SHORTHAND
mas_height
, and so on mas_centerX
.
The following example of the VFL statement above is implemented using the masonry framework, and a comparison will reveal how easy it is to have an automatic layout after the masonry framework:
//创建蓝色控件UIView *blueView = [[UIView alloc] init];blueView.backgroundColor = [UIColor blueColor];[self.view addSubview:blueView];//创建红色控件UIView *redView = [[UIView alloc] init];redView.backgroundColor = [UIColor redColor];[self.view addSubview:redView];// 添加blueView的约束[blueView makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(redView.width).offset(0); make.height.equalTo(redView.height).offset(0); make.height.equalTo(100); make.left.equalTo(blueView.superview.left).offset(20); make.bottom.equalTo(blueView.superview.bottom).offset(-20); make.right.equalTo(redView.left).offset(-20);}];// 添加redView的约束[redView makeConstraints:^(MASConstraintMaker *make) { make.bottom.equalTo(redView.superview.bottom).offset(-20); make.right.equalTo(redView.superview.right).offset(-20);}];
Masonry framework provides a lot of sample programs, interested can open the above github link download down to study carefully, here is not much to write.
GitHub links to: Https://github.com/SnapKit/Masonry
Constraint animations:
Remember to call the following methods when performing animations:
//在修改了约束之后,只要执行下面代码,约束就能做出动画效果[UIView animateWithDuration:0.5 animations:^{ [self.view layoutIfNeeded]; }];
Use AutoLayout to implement Uilabel content wrapping:
- 1. Setting the position constraint of Uilabel
- 2, set
label.numberOfLines = 0;
, so that label can automatically wrap to calculate the height
- 3. When the code creates a constraint, the maximum width of the label should be set
preferredMaxLayoutWidth
.
Automatic layout of iOS learning-autolayout