1.程序中导入 Masonry 库,并在需要使用的文件中添加头文件 Masonry.h
2.在使用Masonry 添加约束之前,一定要先将你需要添加的约束控件添加到父视图中.
否则直接CRASH
reason: 'couldn't find a common superview for <UIView: 0x7ffa29d2c2c0; frame = (0 0; 0 0);
layer = <CALayer: 0x7ffa29d25e70>> and <UIView: 0x7ffa29d23640; frame = (0 0; 414 736);
autoresize = W+H; layer = <CALayer: 0x7ffa29d15670>>'
3.在Masonry中我们主要使用的就是下面这三个方法
//
使用
mas_makeConstraints
创建
constraint
后,你可以使用局部变量或属性来保存以便下次引用它;如果创建多个
constraints
,你可以采用数组来保存它们
- (
NSArray
*)mas_makeConstraints:(
void
(^)(
MASConstraintMaker
*))block {
}
//
有时你需要更新
constraint(
例如,动画和调试
)
而不是创建固定
constraint
,可以使用
mas_updateConstraints
方法
- (
NSArray
*)mas_updateConstraints:(
void
(^)(
MASConstraintMaker
*))block {
}
//mas_remakeConstraints
与
mas_updateConstraints
比较相似,都是更新
constraint
。不过,
mas_remakeConstraints
是删除之前
constraint
,然后再添加新的
constraint(
适用于移动动画
)
;而
mas_updateConstraints
只是更新
constraint
的值
- (
NSArray
*)mas_remakeConstraints:(
void
(^)(
MASConstraintMaker
*make))block {
}
4.关于添加约束中要使用的属性,主要有下面几种
补充一下
NSLayoutAttributeLeft/NSLayoutAttributeRight 和 NSLayoutAttributeLeading/NSLayoutAttributeTrailing的区别是left/right永远是指左右,而leading/trailing在某些从右至左习惯的地区会变成,leading是右边,trailing是左边
并且在 iOS8 出现之后,又添加了许多的属性.
typedef
NS_ENUM
(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft =
1
,
NSLayoutAttributeRight,
NSLayoutAttributeTop,
NSLayoutAttributeBottom,
NSLayoutAttributeLeading,
NSLayoutAttributeTrailing,
NSLayoutAttributeWidth,
NSLayoutAttributeHeight,
NSLayoutAttributeCenterX,
NSLayoutAttributeCenterY,
NSLayoutAttributeBaseline,
NSLayoutAttributeLastBaseline =
NSLayoutAttributeBaseline
,
NSLayoutAttributeFirstBaseline
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeLeftMargin
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeRightMargin
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeTopMargin
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeBottomMargin
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeLeadingMargin
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeTrailingMargin
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeCenterXWithinMargins
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeCenterYWithinMargins
NS_ENUM_AVAILABLE_IOS
(
8
_0),
NSLayoutAttributeNotAnAttribute =
0
};
有的同学可能会有疑问,新添加的属性和之前的属性好像没有什么区别呀
这里我采用可视化的方法展示.
在界面上布置一个 Label ,对它添加约束.这时候应该是这个样子
但是,我们打开界面右下方的Pin , 发现这里为什么有一个勾选呢? 如果我们去掉勾选添加约束呢?
这时候我们能看到,可以正常添加属性,同时这两个约束也同时存在,查看约束属性,发现属性名称也是相同,但是具体数值却不同.接下来往下看.
细心同学可能已经发现了,在左侧的数值一栏显示的名称不一样.
这里就提到 iOS 8 里添加的属性 --
margins ,
如果你点了constrain to margins,左右会有8个点的空挡,而是从8个点后开始计算约束,而没有点时,已屏幕的0点开始计算。
这里需要注意一点,如果你的视图是 StroyBoard, 那么你的 margins 属性会给你在左右偏移20像素,而上下不会变.
如果你的视图是 .Xib 文件,则你的 margins 属性会在你的上下左右全部添加8个像素.
(PS: 苹果可视化推荐的间距就是8像素,大家可以注意一下)
了解了基础属性,下面就正式进入代码阶段,来个小项目练练手.
为了方便第一次使用的同学阅读,每个视图的约束都尽量设置全,方便理解.
//
将三个视图添加进父视图
UIView
*greenView = [[
UIView
alloc
]
init
];
greenView.
backgroundColor
= [
UIColor
redColor
];
[
self
.
view
addSubview
:greenView];
UIView
*redView = [[
UIView
alloc
]
init
];
redView.
backgroundColor
= [
UIColor
blueColor
];
[
self
.
view
addSubview
:redView];
UIView
*blueView = [[
UIView
alloc
]
init
];
blueView.
backgroundColor
= [
UIColor
greenColor
];
[
self
.
view
addSubview
:blueView];
int
padding =
10
;
//
添加约束
[greenView
mas_makeConstraints
:^(
MASConstraintMaker
*make) {
//Masonry
中添加属性基本都是
make
开头
//equalTo :
表示
添加属性
和
某个视图或者位置
相等
//offset :
表示
对前面
self.view.mas_left
这个位置偏移多少
//multipliedBy :表示这个视图占之前的视图大小的几分之几,0.5就是占一半
//center :
表示
这个视图和之前的视图中心点的位置
make.
top
.
equalTo
(
self
.
view
.
mas_top
) .
offset
(
0
);
make.
left
.
equalTo
(
self
.
view
.
mas_left
) .
offset
(
0
);
make.
width
.
equalTo
(
self
.
view
.
mas_width
) .
multipliedBy
(
0.5
);
make.
height
.
equalTo
(
self
.
view
.
mas_height
).
multipliedBy
(
0.5
);
}];
[redView
mas_makeConstraints
:^(
MASConstraintMaker
*make) {
make.
top
.
equalTo
(greenView.
mas_top
);
make.
left
.
equalTo
(greenView.
mas_right
).
offset
(padding);
//
当我们有多个属性和某个视图是完全一样的时候
,
我们可以使用
and
或者
with
关键词进行连接
make.
height
.
and
.
width
.
equalTo
(greenView);
}];
[blueView
mas_makeConstraints
:^(
MASConstraintMaker
*make) {
make.
top
.
equalTo
(greenView.
mas_bottom
).
offset
(padding);
make.
bottom
.
equalTo
(
self
.
view
).
offset
(-padding);
make.left .equalTo(self.view).offset(padding);
make.
right
.
equalTo
(
self
.
view
).
offset
(-padding);
//
这里需要注意
,
我们添加约束还可以使用
mas_equalTo
//mas_equalTo :
后面的约束条件是数值或者结构体等类型
,
其本质就是
对其参数进行了一个
BOX
操作
(
装箱
)
//
一般将数值类型的约束用
mas_equalTo
,而相对于某个控件,或者某个控件的某个约束,使用
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.
*/
}];
最后也推荐一篇相关的博客 : http://www.jianshu.com/p/2ed5f7444900#
补充一个看到的小技巧博客 : http://www.brighttj.com/ios/ios-masonry-demo.html#comment-353
当键盘挡住输入框时,输入框自动向上弹到键盘上方。
这里需要使用到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];
}];
}
更多精彩文章,尽在我的公众号.