免費開源的iOS開發學習平臺

                                                Auto Layout : 2-Masonry

                                                雖然通過Storyboard可以非常直觀的設置控件之間的約束關系,但是當界面比較復雜的情況下,通過Storyboard來設置約束會非常的難以維護,特別是涉及到團隊開發時,Storyboard絕對不是優選方法。雖然蘋果官方也為我們提供了通過代碼編寫自動布局的類--NSLayoutConstraints類,但是NSLayoutConstraints使用起來也非常的不便。鑒于此,在實際的開發中,我們經常使用第三方SDK--Masonry來替代NSLayoutConstraints。

                                                Masonry簡介

                                                Masonry用漂亮的語法對AutoLayout進行了包裝,是一個輕量級的布局框架。Masonry提供了一種鏈式描述約束的方法,這使得布局的代碼更簡潔和易讀。并且Masonry支持iOS和Mac OS X。

                                                Masonry的安裝

                                                Masonry推薦使用CocoaPods進行安裝。在安裝時,需要在工程的Podfile中添加下方的代碼,然后更新下載即可。

                                                pod 'Masonry'
                                                

                                                在需要使用Masonry的文件中引入頭文件:

                                                #import "Masonry.h"
                                                

                                                Masonry中的常用方法

                                                Masonry是對自動布局Auto Layout的封裝,因此在其中提供了與自動布局相對應的一些針對約束的操作方法,主要包括如下幾個。

                                                • 添加約束。mas_makeConstraints:方法可以用于為所有UIView類添加約束。
                                                - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
                                                
                                                // 創建一個MASConstraint屬性
                                                @property (nonatomic, strong) MASConstraint *topConstraint;
                                                
                                                ...
                                                
                                                // 創建約束
                                                [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
                                                    self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top);
                                                    make.left.equalTo(superview.mas_left).with.offset(padding.left);
                                                }];
                                                
                                                ...
                                                // 不需要的時候可以卸載掉約束
                                                [self.topConstraint uninstall];
                                                
                                                • 更新約束。mas_updateConstraints:方法是用來更新約束的,如果約束存在則更新,如果不存在則添加新的約束。需要額外注意的是,當需要更新視圖的約束時,蘋果官方推薦在updateViewConstraints方法中進行更新。
                                                - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;
                                                
                                                - (void)updateViewConstraints {
                                                    [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
                                                        make.center.equalTo(self);
                                                        make.width.equalTo(@(self.buttonSize.width)).priorityLow();
                                                        make.height.equalTo(@(self.buttonSize.height)).priorityLow();
                                                        make.width.lessThanOrEqualTo(self);
                                                        make.height.lessThanOrEqualTo(self);
                                                    }];
                                                    //在結束時記得調用父類的方法!
                                                    [super updateViewConstraints];
                                                }
                                                
                                                • 重新添加約束。mas_remakeConstraints:方法是用來重新添加約束的,在添加新約束前會先刪除所有約束。
                                                - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;
                                                
                                                - (void)changeButtonPosition {
                                                    [self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
                                                        make.size.equalTo(self.buttonSize);
                                                        if (topLeft) {
                                                            make.top.and.left.offset(10);
                                                        } else {
                                                            make.bottom.and.right.offset(-10);
                                                        }
                                                    }];
                                                }
                                                
                                                • 刪除約束。uninstall用于清除之前添加的所有約束。
                                                - (void)uninstall;
                                                

                                                Masonry中定義的關系

                                                Masonry中有三種關系。

                                                1. .equalTo等價于NSLayoutRelationEqual。
                                                2. .lessThanOrEqualTo等價于NSLayoutRelationLessThanOrEqual。
                                                3. .greaterThanOrEqualTo等價于NSLayoutRelationGreaterThanOrEqual。

                                                這三個方法都接受下面任何一個參數。

                                                • MASViewAttribute。MASViewAttribute與NSLayoutAttribute的對應關系如下。

                                                | MASViewAttribute | NSLayoutAttribute |
                                                | --- | --- |
                                                | view.mas_left | NSLayoutAttributeLeft |
                                                | view.mas_right | NSLayoutAttributeRight |
                                                | view.mas_top | NSLayoutAttributeTop |
                                                | view.mas_bottom | NSLayoutAttributeBottom |
                                                | view.mas_leading | NSLayoutAttributeLeading |
                                                | view.mas_trailing | NSLayoutAttributeTrailing |
                                                | view.mas_width | NSLayoutAttributeWidth |
                                                | view.mas_height | NSLayoutAttributeHeight |
                                                | view.mas_centerX | NSLayoutAttributeCenterX |
                                                | view.mas_centerY | NSLayoutAttributeCenterY |
                                                | view.mas_baseline | NSLayoutAttributeBaseline |

                                                make.centerX.lessThanOrEqualTo(view2.mas_left);
                                                
                                                • UIView。視圖的左邊大于等于label的左邊,下面兩種寫法是等價的。
                                                make.left.greaterThanOrEqualTo(label);
                                                make.left.greaterThanOrEqualTo(label.mas_left);
                                                
                                                • NSNumber。也可以針對寬度和高度設置具體的約束大小。
                                                make.width.greaterThanOrEqualTo(@200);
                                                make.width.lessThanOrEqualTo(@400)
                                                

                                                如果設置left、right、centerY等為一個具體值時意味著它相對于父視圖left、right、centerY的位移。比如下面的代碼是視圖相對于父視圖左邊位移10個點。

                                                //creates view.left = view.superview.left + 10
                                                make.left.lessThanOrEqualTo(@10)
                                                

                                                如果你不想用NSNumer作為參數你可以使用這個以mas_equal...開頭的方法來進行設置。

                                                make.top.mas_equalTo(42);
                                                make.height.mas_equalTo(20);
                                                make.size.mas_equalTo(CGSizeMake(50, 100));
                                                make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));
                                                make.left.mas_equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0));
                                                
                                                • NSArray。equalTo方法也接受一組上面類型的數組。
                                                make.height.equalTo(@[view1.mas_height, view2.mas_height]);
                                                make.height.equalTo(@[view1, view2]);
                                                make.left.equalTo(@[view1, @100, view3.right]);
                                                

                                                示例代碼

                                                我們把上一節在Storyboard中實現自動布局的例子,使用Masonry重寫一遍。首先在控制器中添加三個視圖屬性,并在其getter方法中賦予相對應的顏色。

                                                #import "ViewController.h"
                                                #import <Masonry/Masonry.h>
                                                
                                                @interface ViewController ()
                                                @property (nonatomic, strong) UIView *yellowView;
                                                @property (nonatomic, strong) UIView *greenView;
                                                @property (nonatomic, strong) UIView *redView;
                                                @end
                                                
                                                #pragma mark - Getter
                                                - (UIView *)yellowView {
                                                    if (nil == _yellowView) {
                                                        _yellowView = [[UIView alloc] init];
                                                        _yellowView.backgroundColor = [UIColor yellowColor];
                                                    }
                                                    return _yellowView;
                                                }
                                                
                                                - (UIView *)greenView {
                                                    if (nil == _greenView) {
                                                        _greenView = [[UIView alloc] init];
                                                        _greenView.backgroundColor = [UIColor greenColor];
                                                    }
                                                    return _greenView;
                                                }
                                                
                                                - (UIView *)redView {
                                                    if (nil == _redView) {
                                                        _redView = [[UIView alloc] init];
                                                        _redView.backgroundColor = [UIColor redColor];
                                                    }
                                                    return _redView;
                                                }
                                                
                                                - (void)viewDidLoad {
                                                    [super viewDidLoad];
                                                    
                                                    [self.view addSubview:self.yellowView];
                                                    [self.view addSubview:self.greenView];
                                                    [self.view addSubview:self.redView];
                                                }
                                                

                                                通知UIKit需要使用AutoLayout進行布局。

                                                + (BOOL)requiresConstraintBasedLayout {
                                                    return YES;
                                                }
                                                

                                                在updateViewConstraints方法中使用Masonry來添加和更新約束。

                                                - (void)updateViewConstraints {
                                                    [self.yellowView mas_remakeConstraints:^(MASConstraintMaker *make) {
                                                        make.top.and.leading.equalTo(@20);
                                                        make.width.equalTo(self.greenView);
                                                        make.trailing.equalTo(self.greenView.mas_leading).offset(-20);
                                                    }];
                                                    
                                                    [self.greenView mas_remakeConstraints:^(MASConstraintMaker *make) {
                                                        make.top.equalTo(@20);
                                                        make.trailing.equalTo(@(-20));
                                                        make.width.equalTo(self.yellowView);
                                                        make.leading.equalTo(self.yellowView.mas_trailing).offset(20);
                                                    }];
                                                    
                                                    [self.redView mas_remakeConstraints:^(MASConstraintMaker *make) {
                                                        make.leading.equalTo(@20);
                                                        make.bottom.and.trailing.equalTo(@(-20));
                                                        make.top.equalTo(@[self.yellowView.mas_bottom,self.greenView.mas_bottom]).offset(20);
                                                        make.height.equalTo(@[self.yellowView, self.greenView]);
                                                    }];
                                                    
                                                    [super updateViewConstraints];
                                                }
                                                

                                                運行效果如下。

                                                ![屏幕快照 2016-12-20 上午10.09.27](http://oifaewd5m.bkt.clouddn.com/屏幕快照 2016-12-20 上午10.09.27.png)

                                                ![屏幕快照 2016-12-20 上午10.09.38](http://oifaewd5m.bkt.clouddn.com/屏幕快照 2016-12-20 上午10.09.38.png)


                                                欧美超级精品一级A片|欧美一级黄色视频|国产精品自在在线午夜免费|4444亚洲人成无码网在线观看|亚洲ⅴa曰本va欧美va视频