Masonry 学习笔记

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 , 发现这里为什么有一个勾选呢?   如果我们去掉勾选添加约束呢?
Masonry 学习笔记_第1张图片
这时候我们能看到,可以正常添加属性,同时这两个约束也同时存在,查看约束属性,发现属性名称也是相同,但是具体数值却不同.接下来往下看.

Masonry 学习笔记_第2张图片
细心同学可能已经发现了,在左侧的数值一栏显示的名称不一样.
Masonry 学习笔记_第3张图片
这里就提到 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];
     }];
}


更多精彩文章,尽在我的公众号.
Masonry 学习笔记_第4张图片

你可能感兴趣的:(ios,masonry,自动布局,autolayout,纯代码布局)