Use Masonry to build a special layout and compare it with xib.

Source: Internet
Author: User
Tags control label

Use Masonry to build a special layout and compare it with xib.

Previously, only a relatively small number of contacts with Masonry. Most of the layout s in the project are combined with the AutoLayout in the xib with the frame computing of the hand code. I believe there will also be a combination of the two layout s like me. In fact, xib works well in all aspects. In the past, it was a performance problem and the conflict problem was criticized. However, with the upgrade of apple, these problems gradually tend to be minimized. The main reason for our team's rectification is to improve fine-grained componentization. Because reusing a piece of code to another page is far faster than dragging several controls from xib to another page, and the code written using Masonry is very clear and easy to understand in the relationship between controls.

The general layout is omitted. Here we will build some special la S.

If you do not see this article in Dong baoran blog, click to view the original article.

1. There are three uiviews or UIButton at the bottom, and the height of the screen width (horizontal screen and vertical screen) must always be equal to or higher.

 

The right figure above is built under xib. The general Masonry syntax is used to complete the layout code.

    [redView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.equalTo(self.view.mas_left).with.offset(0);        make.bottom.equalTo(self.view.mas_bottom).with.offset(0);        make.height.equalTo(@100);    }];        [blueView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.equalTo(redView.mas_right).with.offset(0);        make.bottom.equalTo(self.view.mas_bottom).with.offset(0);        make.width.equalTo(redView.mas_width).with.offset(0);        make.height.equalTo(redView.mas_height).with.offset(0);    }];        [greenView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.equalTo(blueView.mas_right).with.offset(0);        make.bottom.equalTo(self.view.mas_bottom).with.offset(0);        make.right.equalTo(self.view.mas_right).with.offset(0);        make.width.equalTo(blueView.mas_width).with.offset(0);        make.height.equalTo(blueView.mas_height).with.offset(0);    }];

The specific logic is very clear in the code. You can clearly understand the relationship between controls. Basically, each row represents a constraint in xib.

In addition, Masonry supports some omitting and simple writing:

If the relationship between the two controls at the same position (constraint), only the control constraints written in the brackets can be omitted;

If the constraint depends on the same control, you can use and to connect the two constraints to one row;

If the offset is 0, the with. offset (0) following the offset can be omitted;

The code above can be written as follows:

    [redView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.bottom.equalTo(self.view);        make.height.equalTo(@100);    }];        [blueView mas_makeConstraints:^(MASConstraintMaker *make) {        make.bottom.and.width.and.height.equalTo(redView);        make.left.equalTo(redView.mas_right);    }];        [greenView mas_makeConstraints:^(MASConstraintMaker *make) {        make.bottom.and.width.and.height.equalTo(blueView);        make.right.equalTo(self.view);        make.left.equalTo(blueView.mas_right);    }];

Note: If the functions of these modules are similar, we recommend that you package a parent Control for easy operations and separation of the entire component. In addition, the project structure can be clearer from a macro perspective.

 

2. implement automatic layout of mutual dependencies. The height of the background View is determined by how long the Label of the Child control can be pulled.

The simple description is that the Left and top of the label depend on the parent control grayView. However, the bottom of the parent grayView is dependent on the sub-control Label.

The figure above shows the AutoLayout built on the IB page, but the code written based on the idea of xib is problematic.

    [grayView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(self.view).with.offset(50);        make.width.equalTo(@200);        make.bottom.equalTo(contentLbl).with.offset(10);    }];        [contentLbl mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(grayView).with.offset(10);        make.right.equalTo(grayView).with.offset(-10);    }];

The code above will cause a crash because the contentLbl constraints on the above 4th rows have not yet been set up, which leads to a crash. The red arrow appears in the xib, that is, the constraint error. After the constraint is adjusted correctly, the red arrow turns into a yellow arrow, that is, the constraint is correct. However, unlike xib, the use of Masonry allows you to correct errors. As long as an error occurs, Masonry will crash immediately. Therefore, for this type of dependency constraint, it seems impossible for the following constraint to be created. The actual solution is to use the sub-control to depend on him in turn. That is to say, you want the parent control to depend on the Child control 10 pixels more than the child control, and it is equivalent to setting the child control to depend on the parent control 10 pixels less than the child control, which can be converted to each other. If you are a careful netizen, you will find that in xib, although you set the parent control to depend on the Child control, the actual constraints are still placed in the Child control.

The modified code is as follows:

    [grayView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(self.view).with.offset(50);        make.width.equalTo(@200);    }];        [contentLbl mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(grayView).with.offset(10);        make.right.equalTo(grayView).with.offset(-10);        make.bottom.equalTo(grayView).with.offset(-10);    }];

 

3. Set the percentage constraint, that is, the percentage of one constraint to the other.

This constraint is generally applicable to width and height. It is useful for screen adaptation. It is equivalent to adding the previously computed frame idea to autoLayout.

    [grayView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(self.view).with.offset(50);//        make.width.equalTo(@200);        make.width.equalTo(self.view).multipliedBy(0.5).offset(0);    }];        [contentLbl mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(grayView).with.offset(10);        make.right.equalTo(grayView).with.offset(-10);        make.bottom.equalTo(grayView).with.offset(-10);    }];

Like the native constraint, you can set another offset after setting the vector coefficient (proportion.

 

4. Update Constraints

Currently, there are multiple third-party libraries automatically deployed, and Masonry is also heavyweight. Compared with other auto-layout libraries, Masonry performs well in updating constraints.

Assume that the current constraint is the one in the preceding 2nd cases. Click "Update constraint" as shown in the following code.

- (IBAction)btnclick:(id)sender {    [self.grayView mas_updateConstraints:^(MASConstraintMaker *make) {        make.width.equalTo(@300);    }];    [UIView animateWithDuration:3.0 animations:^{        [self.grayView layoutIfNeeded];    }];}

If you want to change the constraint, use the block of the UIView animation to wrap the layoutIfNeed. Instead of wrapping the constraint update directly.

Note the essential differences between mas_updateConstraints and mas_remakeConstraints when updating constraints. The former update is to retain the previous constraints and then add your new constraints. If a method with the same setting constraints is displayed, but the values are different, the original constraints are replaced directly. The latter remake directly kills all the original ones, and then adds the constraints for this setting.

Therefore, do not add constraints with the new method to the update statement, which may conflict with the preceding constraints. Note that the constraints you write in remake must be a complete constraint, because the previous constraints are all cleared.

If the difference between the two methods is not fully clarified, the following code may be written, which is wrong.

- (IBAction)btnclick:(id)sender {    [self.grayView mas_updateConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(self.view).with.offset(10);        make.width.equalTo(self.view).multipliedBy(0.5);    }];        [UIView animateWithDuration:3.0 animations:^{        [self.grayView layoutIfNeeded];    }];}

Because the original make. width. similar to (@ 200); and make. width. similar to (self. view ). multipliedBy (0.5); although the width is set but the setting method is different, the new and old values will be retained, resulting in an error of conflict.

If you do not see this article in Dong baoran blog, click to view the original article.

 

5. set priority and Label anti-compression

Sometimes, XX may occur when the Label width or internal font changes, because the Label is compressed. Masonry has anti-compression settings, and this setting is closely related to the priority of Masonry. The changes in the iOS9 font lead to many labels... If Masonry was used to set the layout and set anti-compression, this problem should be completely avoided.

Set a View with a sub-control Label.

    [blackView mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.equalTo(self.view).with.offset(50);        make.top.equalTo(self.view).with.offset(300);        make.size.mas_equalTo(CGSizeMake(200, 50));    }];        [contentLbl2 mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(blackView).with.offset(10);        make.right.equalTo(blackView).with.offset(-50);        make.height.equalTo(@30);    }];

The first code above is to build a common parent control that can be ignored. The following is a Label constraint.

If this is set, the right side is 50 less than the parent control, so the Label text cannot be displayed, and will be accumulated.

 

However, if you add a constraint: "The width is at least 200", and set the priority for this constraint to be higher than the "50 fewer than the parent control on the right", the Code is as follows:

    [contentLbl2 mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(blackView).with.offset(10);        make.width.greaterThanOrEqualTo(@200).priority(900);        make.right.equalTo(blackView).with.offset(-50).priority(800);        make.height.equalTo(@30);    }];

Because the priority of the 3rd rows is higher than that of the 4th rows, the Label is not squashed.

 

Another setting method is available for anti-compression.

    [contentLbl2 mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(blackView).with.offset(10);        make.right.equalTo(blackView).with.offset(-50).priority(990);        make.height.equalTo(@30);    }];        [contentLbl2 setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];

Set the priority of "50 less than the parent control on the right" to 1000 or lower, and then write a row of horizontal compression-resistant code below. Note that the above "50 lower than the parent control on the right" priority cannot be left blank, because the default priority of Masonry code is 1000, and the following UILayoutPriorityRequired code has a priority of 1000, the following code is ineffective.

 

In fact, there is a simpler setting method. You do not need to write the horizontal direction to Resist compression. You only need to change the priority after the above constraint to less than 750.

    [contentLbl2 mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.and.top.equalTo(blackView).with.offset(10);        make.right.equalTo(blackView).with.offset(-50).priority(749);        make.height.equalTo(@30);    }];

Because the priority enumeration corresponding to priority 750 is UILayoutPriorityDefaultHigh, it can be understood that Masonry itself has a compression-resistant protection with a priority of 750.

    [contentLbl2 setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];

This line of code should exist by default for all labels.

Therefore, if you want to prevent Label compression, you can set the priority to below 750.

 

Summary:

1. There are not many Masonry methods. The chained method returns a constraint object for each vertex syntax. Specific constraints are attributes of this object.

2. Unlike the xib construction constraints, Masonry can be adjusted in red. When a problem occurs in the former, the former crashes and the problem is stuck in the development stage.

3. Before creating a constraint, Masonry must set up the parent-child relationship and cannot add dependencies to controls without any constraints.

4. The update constraints should clarify the differences between remake and update.

Reprinted without authorization

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.