Overview
Using objective-c Pure code to write AutoLayout, see AutoLayout's literal understanding is the automatic layout , sounds like a pretty dick look. It's all about adaptation and compatibility with a variety of situations, including the adaptation of different versions of the operating system ( system adaptation ) and the adaptation of different screen sizes ( screen fit ).
In Storyboard, AutoLayout has the following 3 commonly used panels:
Align (Align)
Align (Align)
Pin (relative)
Pin (relative)
Resolve Auto Layout issues (constrained processing)
Resolve Auto Layout issues (constrained processing)
In the Storyboard implementation of AutoLayout I do not explain in this article, because it is a violation of the beginner's mind do not forget, Fang has always been the title.
Do not forget beginner's mind, Fang always talk about is cheap, show me the Code
Let's start with the code to implement the AutoLayout step, don't blink:
Use NSLayoutConstraint
the class to create a specific constraint object;
To add a constraint object to the corresponding view, there are two types of code:
- (void)addConstraint:(NSLayoutConstraint *)constraint;- (void)addConstraints:(NSArray *)constraints;
Perhaps someone asked, originally only two steps on it, I just took off the trousers, you give me to see this?!
Say not more, immediately show you the code!
Let's look at the way we use frame to determine the location of a view:
- (void)viewDidLoad { [super viewDidLoad]; self.title = @"使用 frame 的方式"; UIView *purpleView = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 150, 150)]; purpleView.backgroundColor = [UIColor purpleColor]; [self.view addSubview:purpleView];}
The code is simple and works as follows:
Run effect
Then look at the implementation of AutoLayout:
- (void) Viewdidload {[Super Viewdidload];Self. title =@ "How to use AutoLayout";UIView *purpleview = [[UIView alloc] init]; Purpleview. backgroundcolor = [Uicolor Purplecolor];Disable converting Autoresizingmask to Constraints Purpleview. translatesautoresizingmaskintoconstraints =NO; [Self. View Addsubview:purpleview];Add width ConstraintNslayoutconstraint *widthconstraint = [Nslayoutconstraint Constraintwithitem:purpleview attribute:Nslayoutattributewidth Relatedby:Nslayoutrelationequal Toitem:Nil attribute:Nslayoutattributenotanattribute multiplier:0.0 constant:150]; [Purpleview Addconstraint:widthconstraint];Add height ConstraintNslayoutconstraint *heightconstraint = [Nslayoutconstraint Constraintwithitem:purpleview attribute:Nslayoutattributeheight Relatedby:Nslayoutrelationequal Toitem:Nil attribute:Nslayoutattributenotanattribute multiplier:0.0 constant:150]; [Purpleview Addconstraint:heightconstraint];Add a Left constraintNslayoutconstraint *leftconstraint = [Nslayoutconstraint Constraintwithitem:purpleview attribute:Nslayoutattributeleft Relatedby:Nslayoutrelationequal Toitem:Self. View attribute:nslayoutattributeleft multiplier:1.0 constant:100"; [self.view Addconstraint:leftconstraint]; //add top constraint nslayoutconstraint *topconstraint = [ nslayoutconstraint Constraintwithitem:purpleview attribute: nslayoutattributetop relatedby:NSLayoutRelationEqual Toitem:self.view attribute: Nslayoutattributetop multiplier:1.0 constant:200]; [self.view Addconstraint:topconstraint];}
After reading this piece of code, I received a fright! I was frightened by this large piece of code, many children's shoes to see so simple layout need to write so much code, may be scared away. I can only say one thing: don't go, wait for me to explain slowly ~
- Common methods for creating constraint objects (Nslayoutconstraint)
An NSLayoutConstraint
object represents a constraint.
+ (id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
There are a total of 7 parameters??, then take Leftconstraint as an example, let's introduce these 7 parameters.
? View1: The control to constrain (Purpleview)
? ATTR1: The type of constraint (constant), is to do what kind of constraint, you can go in and see what constant (here is Nslayoutattributeleft)
? Relation: Relationship (constant) to the reference control, including equals, greater than, equal to, or less than equals (nslayoutrelationequal is equal to)
? VIEW2: Referenced controls (Self.view)
? ATTR2: The type of constraint (constant), is to do what kind of constraint, you can go in and see what constant (Here is Nslayoutattributeleft) (Nslayoutattributeleft)
? Multiplier: Multiplier, that's how many times (1.0)
? C: Constant, after doing the above constraints will be added to this constant (100)
So Leftconstraint is the delegate: the control you want to constrain is the plus of the purpleView
左间距
等于
reference control self.view
左间距
1.0 倍
100
.
So we come to the core calculation formula of AutoLayout:
value
- Rules for adding constraints (AddConstraint)
After you create the constraint, you need to add it to the control to take effect, and note that when you add the constraint, the target control needs to follow these rules (here the control is simply represented by the view):
(1) For a constraint relationship between two view levels, add to their parent view
For a constraint relationship between two view levels, add to their parent view
(2) for the constraint relationship between two different levels of view, add to their nearest common parent view
For the constraint relationship between two different levels of view, add to their nearest common parent view
(3) For a hierarchical relationship between the two view constraints, added to the higher level of the parent view
For a hierarchical relationship between the two view constraints, added to the higher level of the parent view
(4) For example, the length of the wide and so on, only in the view of their own body, add to the view itself, do not have the map??
It can be seen that widthconstraint and Constraint belong to (4) species, and leftconstraint and Rightconstraint belong to (3).
- Code implementation AutoLayout Considerations
If you just create and add constraints, it does not work, do the following:
(1) To prohibit the autoresizing function, to prevent autoresizingmask conversion to Constraints, to avoid conflict, you need to set the view below the property is NO:view.translatesAutoresizingMaskIntoConstraints = NO;
(2) Before adding constraints, make sure that the relevant controls are already on their parent controls. Using the above example is [Self.view Addsubview:purpleview]; Be sure to put the left constraint before you add it, or the program will crash because you want to ensure that the Purpleview is already on the Self.view. Recommended first write [Self.view Addsubview:purpleview]; After that, concentrate on writing the constraints.
(3) No need to set frame to view
See, then a simple interface, with the AutoLayout implementation of the words should be so much code, it is not so convenient to feel, right?
In fact AutoLayout to see the application content decision, above is just a use of demo. If your content is a large number of information, but also need to show a lot of categories, size dynamic, such as micro-blog list, QQ dynamic list and so on, write these complex interface using AutoLayout can give (jǐyǔ?? ) a lot of help.
In order to simplify AutoLayout complex code, Apple developed a VFL language (Visual format language), in fact, did not see how much simplification, and there are relatively large limitations, here does not introduce, want to understand the children's shoes themselves Google go.
Forget it, give me an official link:
Https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html
How elegant the code is written AutoLayout
It's disgusting to see how Apple comes up with AutoLayout implementations, so how do you write elegant code AutoLayout?
--Use a third-party framework masonry.
Github:https://github.com/snapkit/masonry
Look at its introduction, feel the cow break:
Harness the power of AutoLayout NSLayoutConstraints with a simplified, chainable and expressive syntax. Supports iOS and OSX Auto Layout.
After reading the readme.md file found it was quite elegant.
First glance at how masonry is implemented AutoLayout:
#import"ViewController.h"#import"Masonry.h"//third party or write it yourself in quotation marks, the system comes with double quotation marks.@interfaceViewcontroller ()@end@implementationviewcontroller-(void) Viewdidload {[super viewdidload]; UIView *purpleview = [[UIView alloc] init]; Purpleview. backgroundcolor = [uicolor purplecolor]; [self. View Addsubview:purpleview]; [Purpleview mas_makeconstraints:^ (Masconstraintmaker *make) { //within this block, create constraints using Make object make. Size. Mas_equalto (cgsizemake (+ )); Center. Mas_equalto (selfView);}];}
Operating effect:
Create a view with a length and width of 100, centered on the parent view
Note: purpleView.translatesAutoresizingMaskIntoConstraints = NO;
no need to write here, because masonry is already written.
Masonry, get in the car.
Step by step follow, haha hee
// 长宽均为 100,粘着父 view 右下角 [purpleView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(@100); make.height.equalTo(@100); make.right.equalTo(self.view); make.bottom.equalTo(self.view); }];
100 long and wide, glued to the lower right corner of the parent view
// 长宽均为 100,粘着父 view 右下角,间距为 16 [purpleView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(@100); make.height.equalTo(@100); // 这里也可以写 make.right.equalTo(self.view.mas_right).offset(-16); // 为了增强可读性,可以在 .offset 前加上 .with 或者 .and: make.right.equalTo(self.view).with.offset(-16); 看自己习惯吧 make.right.equalTo(self.view).offset(-16); // 这里也可以写 make.right.equalTo(self.view.mas_bottom).offset(-16); make.bottom.equalTo(self.view).offset(-16); }];
Long and wide are 100, glued to the lower right corner of the parent view, with a spacing of 16
See the above code packaging good @100, in fact, can also be directly passed the value of 100, but to equalTo
change mas_equalTo
, so it will automatically help you package.
make.width.mas_equalTo(100);make.height.mas_equalTo(100);
mas_equalTo
is actually a macro, you can go inside to see the definition.
mas_equalTo
This method will wrap the parameters
equalTo
This method does not wrap the parameters
mas_equalTo
The function is stronger thanequalTo
People may feel a little dizzy, sometimes with, mas_equalTo
sometimes with equalTo
, in fact, you can define two macros in the PCH file, you can solve this tangled problem perfectly. Note to write in #import "Masonry.h"
front.
use Masonry without the ‘mas_‘ prefix,这样子 `mas_width` 等就可以写成 `width`#define MAS_SHORTHAND//define this constant if you want to enable auto-boxing for default syntax,这样子 `mas_equalTo` 和 `equalTo` 就没有区别了#define MAS_SHORTHAND_GLOBALS
OK, now come a little bit more complicated than just the interface:
- (void) Viewdidload {[Super Viewdidload];UIView *purpleview = [[UIView alloc] init]; Purpleview. backgroundcolor = [Uicolor Purplecolor]; [Self. View Addsubview:purpleview];UIView *orangeview = [[UIView alloc] init]; Orangeview. backgroundcolor = [Uicolor Orangecolor]; [Self. View Addsubview:orangeview];CGFloat margin =16;CGFloat height =32; [Purpleview mas_makeconstraints:^ (Masconstraintmaker *make) {Make. Left. Equalto (Self. View). offset (margin); Make. Bottom. Equalto (Self. View). offset (-margin); Make. Right. Equalto (Orangeview. left). Offset (-margin), make. Height. Equalto (height), make. Width. Equalto (Orangeview); }]; [Orangeview mas_makeconstraints:^ (Masconstraintmaker *make) {make. Bottom. Equalto (self. View). Offset (-margin); . View) . Offset (-margin); make. Height. Equalto (height);}];}
Two equal high width view split screen width with gap
In fact, to achieve this interface has a lot of writing, you can try, for example, write:
- (void)viewDidLoad { ... [purpleView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.view).offset(margin); make.bottom.equalTo(self.view).offset(-margin); make.right.equalTo(orangeView.left).offset(-margin); make.height.equalTo(height); make.height.equalTo(orangeView); make.width.equalTo(orangeView); make.top.equalTo(orangeView); }]; [orangeView mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.view).offset(-margin); }];}
Wen/angelen (author of Jane's book)
Original link: http://www.jianshu.com/p/3c7e202c76b2
Copyright belongs to the author, please contact the author to obtain authorization, and Mark "book author".
How elegant the code is written AutoLayout