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中有三种关系。
.equalTo
等价于NSLayoutRelationEqual
。.lessThanOrEqualTo
等价于NSLayoutRelationLessThanOrEqual
。.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];
}
运行效果如下。


最后编辑时间为: September 22nd , 2017 at 01:28 am
本文由 99ios 创作,转载请注明出处