文章來自http://www.brighttj.com/ios/ios-masonry-demo.html#comment-353html
若是說自動佈局解救了多屏幕適配,那衆多三方庫的出現就解救了系統自動佈局的寫法。Masonry就是其中一個。
在Github上,Masonry已經獲得6000+個star,用法上也比較簡單靈活,很大程度上替代了傳統的NSLayoutConstraint佈局方式。本文將利用幾個案例來說解Masonry的使用。Masonry下載地址:
https://github.com/SnapKit/Masonryios
本文Demo下載地址:
https://github.com/saitjr/MasonryDemo.gitgit
Mac OS X 10.10.3
Xcode 6.3
iOS 8.3github
1. 下載Masonry並導入到工程中; 2. 將Masonry.h導入當前控制器。
要求:
不管在什麼尺寸的設備上(包括橫豎屏切換),紅色view都居中顯示。app
實現:佈局
#import "ViewController.h" #import "Masonry.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 防止block中的循環引用 __weak typeof(self) weakSelf = self; // 初始化view並設置背景 UIView *view = [UIView new]; view.backgroundColor = [UIColor redColor]; [self.view addSubview:view]; // 使用mas_makeConstraints添加約束 [view mas_makeConstraints:^(MASConstraintMaker *make) { // 添加大小約束(make就是要添加約束的控件view) make.size.mas_equalTo(CGSizeMake(100, 100)); // 添加居中約束(居中方式與self相同) make.center.equalTo(weakSelf.view); }]; } @end
要求:動畫
實現:ui
#import "ViewController2.h" #import "Masonry.h" @interface ViewController2 () @end @implementation ViewController2 - (void)viewDidLoad { [super viewDidLoad]; UIView *blackView = [UIView new]; blackView.backgroundColor = [UIColor blackColor]; [self.view addSubview:blackView]; // 給黑色view添加約束 [blackView mas_makeConstraints:^(MASConstraintMaker *make) { // 添加大小約束 make.size.mas_equalTo(CGSizeMake(100, 100)); // 添加左、上邊距約束(左、上約束都是20) make.left.and.top.mas_equalTo(20); }]; // 初始化灰色view UIView *grayView = [UIView new]; grayView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:grayView]; // 給灰色view添加約束 [grayView mas_makeConstraints:^(MASConstraintMaker *make) { // 大小、上邊距約束與黑色view相同 make.size.and.top.equalTo(blackView); // 添加右邊距約束 (這裏的間距是有方向性的,左、上邊距約束爲正數,右、下邊距約束爲負數) make.right.mas_equalTo(-20); }]; } @end
在上面的案例中,涉及如下內容:code
在Masonry中,and,with都沒有具體操做,僅僅是爲了提升程序的可讀性
make.left.and.top.mas_equalTo(20);
等價於
make.left.top.mas_equalTo(20);htm
equalTo與mas_equalTo
若是約束條件是數值或者結構體等類型,能夠使用mas_equalTo進行包裝。關於這個問題,我也不是很清楚,能夠看看官方的解釋:
Instead of using NSNumber, you can use primitives and structs to build your constraints.By default, macros which support autoboxing are prefixed with mas_. Unprefixed versions are available by defining MAS_SHORTHAND_GLOBALS before importing Masonry.
我通常將數值類型的約束用mas_equalTo,而相對於某個控件,或者某個控件的某個約束,我會使用equalTo,如:
make.size.mas_equalTo(CGSizeMake(100, 100));make.center.equalTo(weakSelf.view);
要求:
實現:
#import "ViewController3.h" #import "Masonry.h" @interface ViewController3 () @end @implementation ViewController3 - (void)viewDidLoad { [super viewDidLoad]; UIView *blackView = [UIView new]; blackView.backgroundColor = [UIColor blackColor]; [self.view addSubview:blackView]; // 給黑色view添加約束 [blackView mas_makeConstraints:^(MASConstraintMaker *make) { // 添加左、上邊距約束 make.left.and.top.mas_equalTo(20); // 添加右邊距約束 make.right.mas_equalTo(-20); }]; view UIView *grayView = [UIView new]; grayView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:grayView]; // 給灰色view添加約束 [grayView mas_makeConstraints:^(MASConstraintMaker *make) { // 添加右、下邊距約束 make.bottom.and.right.mas_equalTo(-20); // 添加高度約束,讓高度等於blackview make.height.equalTo(blackView); // 添加上邊距約束(上邊距 = 黑色view的下邊框 + 偏移量20) make.top.equalTo(blackView.mas_bottom).offset(20); // 添加左邊距(左邊距 = 父容器縱軸中心 + 偏移量0) make.left.equalTo(weakSelf.view.mas_centerX).offset(0); }]; } @end
要求
:
當鍵盤擋住輸入框時,輸入框自動向上彈到鍵盤上方。實現
:
這裏須要使用到Masonry的另一個方法mas_updateConstraints
。這個方法用於更新控件約束。
具體的實現方式能夠下載Demo來看,這裏只貼出鍵盤彈出時的處理代碼:
- (void)keyboardWillChangeFrameNotification:(NSNotification *)notification { // 獲取鍵盤基本信息(動畫時長與鍵盤高度) NSDictionary *userInfo = [notification userInfo]; CGRect rect = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue]; CGFloat keyboardHeight = CGRectGetHeight(rect); CGFloat keyboardDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; // 修改下邊距約束 [_textField mas_updateConstraints:^(MASConstraintMaker *make) { make.bottom.mas_equalTo(-keyboardHeight); }]; // 更新約束 [UIView animateWithDuration:keyboardDuration animations:^{ [self.view layoutIfNeeded]; }]; }