Masonry是一個輕量級的佈局框架 擁有本身的描述語法 採用更優雅的鏈式語法封裝NSAutoLayout, 簡潔明瞭並具備高可讀性 並且同時支持 iOS 和 Max OS X。使用Masonry可以使用簡單的語法進行Autolayout佈局c++
Masonry經常使用屬性與NSLayoutAttrubute的對照表以下
git
Masonry | NSAutoLayout | 說明 |
---|---|---|
view.mas_left | NSLayoutAttributeLeft | 左側 |
view.mas_top | NSLayoutAttributeTop | 上側 |
view.mas_right | NSLayoutAttributeRight | 右側 |
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 | 文本基線 |
.equalTo
至關於NSLayoutRelationEqual
,爲相等.lessThanOr
EqualTo至關於 NSLayoutRelationLessThanOrEqual
,爲小於或者等於.greaterThanOrEqualTo
至關於 NSLayoutRelationGreaterThanOrEqual
,爲大於或等於// **使用UIView/NSView進行比較**
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
//these two constraints are exactly the same
make.left.greaterThanOrEqualTo(label.mas_left);
make.left.right.equalTo(lable);
}];
..
//2. **直接使用NSNumber進行比較**
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
//width >= 200 && width <= 400
make.width.greaterThanOrEqualTo(@200);
make.width.lessThanOrEqualTo(@400)
}];
..
//3. **使用CGFloat**
[subGreenView mas_makeConstraints:^(MASConstraintMaker *make) {
//width >= 200 && width <= 400
make.width.mas_lessThanOrEqualTo(200);
make.width.mas_greaterThanOrEqualTo(400);
}];
複製代碼
兩個同級的view進行約束github
[subGreenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(subGreenView.mas_left).offset(10);
make.right.equalTo(subGreenView.mas_right).offset(10);
}];
複製代碼
能夠經過mas_makeConstraints
關聯View的left, right, top, bottom, centerX, centerY, leading, trailing, width, height
進行佈局。數組
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(sv).with.offset(5); //with 不是必要的,只是方便理解
make.left.equalTo(sv).with.offset(10);
make.bottom.equalTo(sv).offset(15);
make.right.equalTo(sv).offset(20);
}];
複製代碼
或者bash
[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(subRedView);
make.left.equalTo(subRedView);
make.width.equalTo(subRedView);
make.height.equalTo(subRedView);
}];
複製代碼
[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@18);
make.left.equalTo(@16);
make.width.equalTo(@16);
make.height.equalTo(@16);
}];
複製代碼
[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(18);
make.centerY.mas_equalTo(16);
make.width.mas_equalTo(16);
make.height.mas_equalTo(16);
}];
複製代碼
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@[view1, view2]);
make.left.equalTo(@[view1, @100, view3.right]);
}];
複製代碼
數組有多個不合理的值時,老是獲取最小值來使用.至關於來取最小值.An array of a mixture of any of the previous typesapp
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20));
make.size.equalTo(superview).sizeOffset(CGSizeMake(100, 50));
make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10));
}];
複製代碼
至關於框架
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
//.insets
make.top.equalTo(sv).with.offset(5);
make.left.equalTo(sv).with.offset(10);
make.bottom.equalTo(sv).with.offset(-15);//使用offset,統一方向,因此這裏是-15
make.right.equalTo(sv).with.offset(-20);// 統一方向.
//.size
make.width.equalTo(sv).offset(100);
make.height.equalTo(sv).offset(50);
//.centerOfoffset
make.centerX.equalTo(sv).offset(-5);
make.centerY.equalTo(sv).offset(10);
}];
複製代碼
若是要定義須要進行自動佈局更新的約束。好比經過這約束存在來進行動畫效果狀態更新,或者更新刪除約束.
Masonry中有三種方法來更新約束constraints.less
mas_updateConstraints
mas_updateConstraints
能夠用來更新視圖的約束,而mas_makeConstraints
只能用來建立約束. mas_updateConstraints
來更新視圖約束.[self.likeNumberView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.locationView.mas_bottom)
.offset(kTopOffsetOfLikeNumberView);
make.height.mas_equalTo(kHeightOfLikeNumberView);
}];
複製代碼
mas_remakeConstraints
mas_updateConstraints
只能用來更新約束,可是隻能更新已有約束的值,不能刪除已有約束. mas_remakeConstraints
的使用方法與mas_updateConstraints
相同,可是它在更新視圖以前,會刪除以前全部約束,而後再建立新的約束來更新視圖.[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);
}
}];
複製代碼
References
MASConstraint
類型的約束保持在本地,而後經過install
和uninstall
方法來使用和刪除該約束 @property (nonatomic, strong) MASConstraint *topConstraint;
..
[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {
_topConstraint = make.top.equalTo(superView.mas_top).with.offset(10);
//這裏是保存了已經設定好的約束
make.left.equalTo(superView.mas_left).with.offset(10);
}];
..
//以後須要取消的時候
[_topConstraint uninstall];
..
//也能夠安裝
[_topConstraint install];
複製代碼
UILabel
不用設置高度和寬度,設置了高度,字符很容易被截斷2018-03-28 17:50:55.761481+0800 OMI[7256:2846471] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<MASLayoutConstraint:0x1c80bc0e0 SettingsGenderSelectView:0x11be22d30.width == UITableViewCellContentView:0x11be229d0.width>",
"<MASLayoutConstraint:0x1c00adec0 SelectionIndicator:0x11bd160d0.left == OMISingleSelectionView:0x11bd15ed0.left + 20>",
"<MASLayoutConstraint:0x1c00ae220 UILabel:0x11bd16a70.left == OMISelectionIndicator:0x11bd160d0.right + 14>",
"<MASLayoutConstraint:0x1c00ae280 UILabel:0x11bd16a70.right == OMISingleSelectionView:0x11bd15ed0.right + 10>",
"<MASLayoutConstraint:0x1c00af540 SingleSelectionView:0x11bd15ed0.width == OMISettingsGenderSelectView:0x11be22d30.width>",
"<NSLayoutConstraint:0x1c8284d80 UITableViewCellContentView:0x11be229d0.width == 0>"
)
複製代碼
正如輸出中所述,Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger,如今介紹下使用UIViewAlertForUnsatisfiableConstraints的調試方法。ide
在UIViewAlertForUnsatisfiableConstraints添加symbolic breakpoint:佈局
1.打開斷點導航(cmd+7)
2.點擊左下角的+按鈕
3.選擇Add Symbolic Breakpoint
4.在Symbol添加UIViewAlertForUnsatisfiableConstraints
5. 添加po [[UIWindow keyWindow] _autolayoutTrace](OC項目)或expr -l objc++ -O -- [[UIWindow keyWindow] > _autolayoutTrace](Swift項目)
以後你就能夠看到哪裏出錯了:
po [[UIWindow keyWindow] _autolayoutTrace]
UIWindow:0x7f9481c93360
| •UIView:0x7f9481c9d680
| | *UIView:0x7f9481c9d990- AMBIGUOUS LAYOUT for UIView:0x7f9481c9d990.minX{id: 13}, UIView:0x7f9481c9d990.minY{id: 16}
| | *_UILayoutGuide:0x7f9481c9e160- AMBIGUOUS LAYOUT for _UILayoutGuide:0x7f9481c9e160.minY{id: 17}
| | *_UILayoutGuide:0x7f9481c9ebb0- AMBIGUOUS LAYOUT for _UILayoutGuide:0x7f9481c9ebb0.minY{id: 27}
複製代碼
其中AMBIGUOUS相關的視圖就是約束有問題的。0x7f9481c9d990就是有問題視圖的首地址。能夠快速定位到相關子控件。
固然進一步的調試須要LLDB的命令。好比
打印視圖對象:
(lldb) po 0x7f9481c9d990
<UIView: 0x7f9481c9d990; frame = (0 0; 768 359); autoresize = RM+BM; layer = <CALayer: 0x7fc82d338960>>
複製代碼
改變顏色:
(lldb) expr ((UIView *)0x174197010).backgroundColor = [UIColor redColor]
(UICachedDeviceRGBColor *) $4 = 0x0000000174469cc0
複製代碼
剩下的就是去代碼中找到這個視圖,而後修改其約束了。
延伸資料
Auto Layout Guide
Masonry