美文网首页
Masonry中setNeedsLayout、layoutIfN

Masonry中setNeedsLayout、layoutIfN

作者: 话少为环保 | 来源:发表于2017-02-16 00:53 被阅读310次

    最近在学习Masonry在更新约束动画过程中产生了一些疑问:setNeedsLayout、layoutIfNeeded和setNeedsUpdateConstraints、updateConstraintsIfNeeded的区别和联系。
    通过查看前辈的文章和实践个人理解如下:

    -setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用

    -layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)

    -setNeedsUpdateConstraints方法: 标记为需要更新约束,异步调用updateViewConstraints刷新布局,不立即刷新,但updateViewConstraints一定会被调用

    -updateConstraintsIfNeeded方法:如果,有需要刷新的约束,立即调用updateViewConstraints进行布局(如果没有标记,不一定会调用layoutSubviews)

    举个栗子:

    //
    //  ViewController.m
    //  PodDome
    //
    //  Created by ZX on 2017/2/13.
    //  Copyright © 2017年 ZX. All rights reserved.
    //
    
    #import "ViewController.h"
    
     // 只要添加了这个宏,就不用带mas_前缀
    #define MAS_SHORTHAND
     // 只要添加了这个宏,equalTo就等价于mas_equalTo
    #define MAS_SHORTHAND_GLOBALS
     // 这个头文件一定要放在上面两个宏的后面
     #import "Masonry.h"
    
    
    @interface ViewController ()
    @property (nonatomic, strong) UIButton *growingButton;
    @property (nonatomic, assign) CGFloat scacle;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.growingButton = [UIButton buttonWithType:UIButtonTypeSystem];
        [self.growingButton setTitle:@"点我放大" forState:UIControlStateNormal];
        self.growingButton.layer.borderColor = UIColor.greenColor.CGColor;
        self.growingButton.layer.borderWidth = 3;
        
        [self.growingButton addTarget:self action:@selector(onGrowButtonTaped:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:self.growingButton];
        self.scacle = 1.0;
        
        [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
            make.center.mas_equalTo(self.view);
            
            // 初始宽、高为100,优先级最低
            make.width.height.mas_equalTo(100 * self.scacle).priorityLow();
            // 最大放大到整个view
            make.width.height.lessThanOrEqualTo(self.view);
        }];
    }
    
    #pragma mark - updateViewConstraints
    - (void)updateViewConstraints {
        [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
            make.center.mas_equalTo(self.view);
            
            // 初始宽、高为100,优先级最低
            make.width.height.mas_equalTo(100 * self.scacle).priorityLow();
            // 最大放大到整个view
            make.width.height.lessThanOrEqualTo(self.view);
        }];
        
        [super updateViewConstraints];
    }
    
    - (void)onGrowButtonTaped:(UIButton *)sender {
        
        
        self.scacle += 0.5;
        
          // 告诉self.view约束需要更新
    //    [self.view setNeedsUpdateConstraints];
          // 调用此方法告诉self.view检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用
    //    [self.view updateConstraintsIfNeeded];
        
          // 告诉self.view布局需要更新
           [self.view setNeedsLayout];
          // 调用此方法告诉self.view检测是否需要更新布局,若需要则更新,下面添加动画效果才起作用
          [self.view layoutIfNeeded];
        
        [UIView animateWithDuration:0.3 animations:^{
            [self.view layoutIfNeeded];
        }];
    }
    
    
    - (void)viewDidLayoutSubviews {
        
        [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
            make.center.mas_equalTo(self.view);
            
            // 初始宽、高为100,优先级最低
            make.width.height.mas_equalTo(100 * self.scacle).priorityLow();
            // 最大放大到整个view
            make.width.height.lessThanOrEqualTo(self.view);
        }];
    
        
        [super viewDidLayoutSubviews];
    }
    @end
    

    不管约束更新的代码是放在layoutIfNeeded 还是 updateViewConstraints 都能完成约束更新的动画效果。

    补充一点:在控制器中viewDidLayoutSubviews 等价于 layoutSubviews。

    相关文章

      网友评论

          本文标题:Masonry中setNeedsLayout、layoutIfN

          本文链接:https://www.haomeiwen.com/subject/aascwttx.html