iOS interface layout Three--Pure code AutoLayout and layout animationFirst, Introduction
With regard to the interface layout, Apple's strategy has matured and AutoLayout's advantages have been demonstrated in development. In addition to using storyboard to drag and drop layout constraints, sometimes we also need to do AutoLayout layout settings in code, masonry library can easily create constrained properties, in fact, we do not need to use the system native code to create and set constraints, This blog is used only as a reminder of how to use it. The links to the previous layouts are as follows:
Using Autoresizing for interface layout: http://my.oschina.net/u/2340880/blog/423357
Initial knowledge AutoLayout layout model: http://my.oschina.net/u/2340880/blog/423500
Second, understand a class
Use code to make the related constraints between the views, then must be the "constraints" also to object, after iOS6, introduced the concept of AutoLayout, corresponding also added nslayoutconstraint this object, this object is specifically used to constrain the layout of the Settings object. With this object, we can set the spacing between similar view objects, constrain the width of the height, and the proportions of the properties. There are two ways to create a Nslayoutconstraint object, which we describe below:
1. Create a Constraint object using the Objective-c style method
The so-called objective-c style approach is to create Nslayoutconstraint objects by using native enumerations and some property settings. here's how to use the Nslayoutconstraint class:
+ (Instancetype) Constraintwithitem: (id) view1 attribute: (nslayoutattribute) attr1 Relatedby: (nslayoutrelation) Relation Toitem: (nullable ID) view2 attribute: (nslayoutattribute) attr2 multiplier: (cgfloat) Multiplier constant: ( CGFloat) C;
Let's start by describing what the parameters in the method mean, and how we should use them:
View1: The View object to add the constraint to.
Attr1: Object properties to constrain, this is some enumeration, as follows:
Typedef ns_enum (Nsinteger, nslayoutattribute) { nslayoutattributeleft = 1,//left nslayoutattributeright,//right nslayoutattributetop,//on the nslayoutattributebottom,// nslayoutattributeleading,//start edge, similar to left, only in some right-to-left languages and Nslayoutattributeleft have a big difference nslayoutattributetrailing,//End Edge nslayoutattributewidth,//width nslayoutattributeheight,//Height nslayoutattributecenterx,//x Center nslayoutattributecentery,//y Center nslayoutattributebaseline,//Baseline nslayoutattributelastbaseline = nslayoutattributebaseline, Nslayoutattributefirstbaseline ns_enum_available_ios (8_0), //The following properties are set margins meanings and similar above corresponding left and right equilateral margin 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), Nslayoutattributecenterywithinmargins ns_enum_available_ios (8_0), //No, the following will say the application scenario NSLayoutAttributeNotAnAttribute = 0};
Relation: The options for the constraint, corresponding to <=,==,>= these, are enumerated as follows:
typedef ns_enum (Nsinteger, nslayoutrelation) {nslayoutrelationlessthanorequal = -1,//<= nslayoutrelationequal = 0,//== nslayoutrelationgreaterthanorequal = 1,//>=};
View2: The View object with which to add the constraint, for example, if I want to set the top margin of the view1 on the top edge of the parent view, this view2 is the parent view of View1, and if I want to set View1 to a distance from another view, this view2 is another view.
Attr2:view2 the attributes to be constrained, the same as the attr1 meaning.
Multiplie: The ratio of constraints, such as view1 width is twice times the width of view2, this multiplie is 2.
C: This is the specific constraint value
For these properties, there is an explanation on the document:VIEW1.ATTR1 = view2.attr2 * Multiplier + constant
For example, we create a label, fix its width to 100*100, position it in the center of the screen, and we can use the following constraint code:
Uilabel * label = [[uilabel alloc]init]; label.numberoflines = 0; //use code layout need to set this property to no Label.translatesautoresizingmaskintoconstraints = no; label.backgroundcolor = [uicolor redcolor]; //Create an X-centered constraint nslayoutconstraint * constraintx = [nslayoutconstraint constraintwithitem:label Attribute:nslayoutattributecenterx relatedby:nslayoutrelationequal toitem:self.view attribute: nslayoutattributecenterx multiplier:1 constant:0]; //Creating a Y-centered constraint nslayoutconstraint * constrainty = [nslayoutconstraint constraintwithitem : Label attribute:nslayoutattributecentery relatedby:nslayoutrelationequal toitem:self.view attribute:nslayoutattributecentery multiplier:1 constant:0]; //Creating width Constraints NSLayoutConstraint * Constraintw = [nslayoutconstraint constraintwithitem:label attribute: Nslayoutattributewidth relatedby:nslayoutrelationequal toitem:nil attribute: nslayoutattributenotanattribute multiplier:1 constant:100]; //Creating a Height constraint NSLayoutConstraint * constrainth = [NSLayoutConstraint constraintwithitem:label attribute:nslayoutattributeheight relatedby:nslayoutrelationequal toitem:nil attribute:nslayoutattributenotanattribute multiplier:1 constant:100]; //The view must be added to the parent view before adding the constraint [self.view addSubview:label]; [self.view addConstraints:@[constraintx,constrainty,constrainth,constraintw]];
The effect is as follows:
It can be found that such a simple constraint, we use such code to write such a big lump, trouble and not intuitive. So Apple offers us the next way.
2. Use ASCLL characters to create artistic formatting string constraints
See this little headline is not a bright, this title is not in my imagination, Apple's document is written in this way. Very cute, right. the method of creation in relation to Nslayoutconstraint is as follows:
+ (nsarray<__kindof nslayoutconstraint *> *) Constraintswithvisualformat: (NSString *) format options: ( Nslayoutformatoptions) OPTs metrics: (Nullable nsdictionary<nsstring *,id> *) metrics views: (nsdictionary< NSString *, id> *) views;
So let's start by looking at what a formatted string constraint is.
When it comes to formatting string constraints, let's start with something vfl:visual format language--formatting constraint language. Indeed, this thing is written out at first glance really do not know what the ghost, like to set a label, 100 from the top, the left 20, the width of the height are 100, the code is as follows:
label.numberOfLines = 0; Label.translatesautoresizingmaskintoconstraints = no; label.backgroundcolor = [uicolor redcolor]; //[email protected] " 12332322132131233213213 "; [self.view addsubview:label]; NSArray * constraintArray = [NSLayoutConstraint constraintswithvisualformat:@ "H:|-20-[label ([email protected])]" options:0 metrics:nil Views:nsdictionaryofvariablebindings (label)]; nsarray * constraintarray2 = [nslayoutconstraint constraintswithvisualformat:@ "V:|-100-[label ()" options:0 Metrics:nil views:nsdictionaryofvariablebindings (label)]; [self.view Addconstraints:constraintarray]; [self.view addconstraints:constraintarray2];
The effect is as follows:
The code is a lot less, right, but the middle part of the string what thing? Let's explain here.
The VFL language personally, he is very similar to ancient hieroglyphics (not knowing if Apple engineers are inspired by it), and the constraints on the layout are intuitively expressed in symbols, such as:
H:|-20-[label ([email protected])]
The front h stands for horizontal layout or vertical layout, h for horizontal, V for vertical, | For the edge of the parent view, -20-for the View object name to be laid out within the distance 20px,[], the dimension of the constraint in (), the width under H, the height at V, and the number after the @ to represent the priority.
The options parameter in the Create method, used to set the alignment mode, does not need to be able to write 0:
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), NSLayoutFormatAlignAllCenterY = (1 << Nslayoutattributecentery), nslayoutformatalignallbaseline = (1 << nslayoutattributebaseline), nslayoutformatalignalllastbaseline = nslayoutformatalignallbaseline, Nslayoutformatalignallfirstbaseline ns_enum_available_ios (8_0) = (1 << Nslayoutattributefirstbaseline), nslayoutformatalignmentmask = 0xffff, /* choose only one of these three */ nslayoutformatdirectionleadingtotrailing = 0 << 16, // default NSLayoutFormatDirectionLeftToRight = 1 << 16, nslayoutformatdirectionrighttoleft = 2 << 16, nslayoutformatdirectionmask = 0x3 << 16, };
The metrics parameter is a property substitution dictionary, for example, we use the distance to the left edge 20, if the 20 is a variable width, we can change 20 to width, and then configure the dictionary: @{@ "width": @20}, so, in the layout, The system will change the width to 20.
Views are the mapping dictionaries of objects, and the principle is to map object names in strings to real objects, Nsdictionaryofvariablebindings will help us generate such a dictionary, we only need to think about the object can be passed in, if you want to manually create this dictionary, the format is as follows: @{@ "label": Label}.
Third, the use of aotulayout design a chat interface input box
Careful observation of QQ or other chat tools on the application of the input box, you will find that he is very smart, width will be as we enter the number of lines of text to adapt, and this width is not infinite increase, when we text more than a certain number of lines, the width will remain unchanged, the text box can be sliding content, This can be tricky if not autolayout, but using it will find it so easy:
@interface ViewController () <uitextviewdelegate>{ uitextview * textview ; nsarray * array1; nsarray * array2;} @end @implementation viewcontroller- (void) viewdidload { [super Viewdidload]; // do any additional setup after loading the view, typically from a nib. textView = [[UITextView alloc]init]; textview.layer.bordercolor = [[uicolor graycolor]cgcolor]; textview.layer.borderwidth = 1; Textview.translatesautoresizingmaskintoconstraints = no; textview.delegate= self; [self.view addsubview:textview]; array1 = [nslayoutconstraint constraintswithvisualformat:@ "H:|-100-[textView]-100-|" options:0 metrics:nil views:nsdictionaryofvariablebindings (TextView)]; array2 = [nslayoutconstraint constraintswithvisualformat:@ "V:|-150-[textview ()" options : 0 metrics:nil views:nsdictionaryofvariablebindings (TextView)]; [self.view addconstraints:array1]; [self.view addconstraints:array2]; }-( BOOL) TextView: (uitextview *) Textview shouldchangetextinrange: (Nsrange) Range replacementtext: ( nsstring *) text{ //update constraint if When text height is greater than textview height and less than 100 (textview.contentsize.height>textview.frame.size.height&&textview.contentsize.height<100) { float hight =textView.contentSize.height; //removed the previous [self.view removeconstraints :array1]; [self.view removeconstraints:array2]; array1 = [NSLayoutConstraint constraintswithvisualformat:@ "h:|-100-[textview]-100-|" options:0 metrics:nil views:nsdictionaryofvariablebindings (TextView)]; array2 = [nslayoutconstraint constraintswithvisualformat:@ "V:|-150-[ TextView (hight)] " options:0 metrics:@{@" hight ": [Nsnumber numberwithfloat:hight]} views: Nsdictionaryofvariablebindings (TextView)]; [self.view addconstraints:array1]; [self.view addconstraints:array2]; } //Update constraint [self.view updateconStraintsifneeded]; return yes;}
Now, when we enter, the height of the TextView can be adapted to the number of lines of text.
Iv. improving the effect of updating constraints with animations
This is very coll, we have implemented the TextView with the text of the height of the line to adapt, but the effect of the change is very stiff, but also the Apple Animation framework Support AutoLayout, the place just called the update constraint to make the following changes:
[UIView animatewithduration:1 animations:^{[Self.view layoutifneeded]; }];
Try it, the effect of the transformation has been very smooth.
iOS interface layout Three--Pure code AutoLayout and layout animation