Marsonry庫學習筆記

多個相似Controller模板寫法

- (id)initWithTitle:(NSString *)title viewClass:(Class)viewClass {
    self = [super init];
    if (!self) return nil;
    
    self.title = title;
    self.viewClass = viewClass;
    
    return self;
}

- (void)loadView {
    self.view = self.viewClass.new;
    self.view.backgroundColor = [UIColor whiteColor];
}

基本

MASExampleBasicView

    int padding = 10;
    [greenView makeConstraints:^(MASConstraintMaker *make) {
        // greenView頂部距離父視圖頂部間距>=10
        make.top.greaterThanOrEqualTo(superview.top).offset(padding);
        // greenView左邊距離父視圖左邊間距==10
        make.left.equalTo(superview.left).offset(padding);
        // greenView底部距離blueView頂部間距==-10,說明blueView在greenView下方
        make.bottom.equalTo(blueView.top).offset(-padding);
        // greenView右邊距離redView左邊間距==-10,說明redView在greenView右方
        make.right.equalTo(redView.left).offset(-padding);
        // greenView寬度==redView寬度
        make.width.equalTo(redView.width);
        // greenView高度==redView高度
        make.height.equalTo(redView.height);
        // greenView高度==blue高度
        make.height.equalTo(blueView.height);
    }];

更新修改

MASExampleUpdateView

+ (BOOL)requiresConstraintBasedLayout {
    // 我們應該在自定義View中重寫這個方法猛蔽。如果我們要使用Auto Layout布局當前視圖团甲,應該設置為返回YES弟蚀。
    return YES;
}
// 蘋果推薦的更新約束的地方
- (void)updateConstraints {

    [self.growingButton updateConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self);
        // 降低優(yōu)先度浴韭,相當于設置一個最小值
        make.width.equalTo(@(self.buttonSize.width)).priorityLow();
        make.height.equalTo(@(self.buttonSize.height)).priorityLow();
        // 設置最大值不超過self的寬度/高度
        make.width.lessThanOrEqualTo(self);
        make.height.lessThanOrEqualTo(self);
    }];
    
    // 最后才調(diào)用父方法
    [super updateConstraints];
}
- (void)didTapGrowButton:(UIButton *)button {
    self.buttonSize = CGSizeMake(self.buttonSize.width * 1.3, self.buttonSize.height * 1.3);

    // 告訴self約束準備更新
    [self setNeedsUpdateConstraints];

    // 更新約束
    [self updateConstraintsIfNeeded];

    [UIView animateWithDuration:0.4 animations:^{
        // 更新視圖
        [self layoutIfNeeded];
    }];
}

重設

MASExampleRemakeView

重設使用方法remakeConstraints
remakeConstraints和updateConstraints類似,只是remakeConstraints會刪除舊的約束道媚,添加新的約束
而updateConstraints則會更新出現(xiàn)在block里的約束

使用常量

MASExampleConstantsView

Masonry可以使用標量和結構體(CGPoint揍愁、CGSize之類的)

Edges

MASExampleSidesView

[view mas_makeConstraints:^(MASConstraintMaker *make) {
    // 一次設好上下左右間距的方法
    make.edges.equalTo(lastView).insets(UIEdgeInsetsMake(5, 10, 15, 20));
}];

AspectFit

MASExampleAspectFitView

    //設置約束
    [self addSubview:_topView];
    [_topView makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.and.right.equalTo(self);
    }];
    
    [self addSubview:_bottomView];
    [_bottomView makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.and.bottom.equalTo(self);
        make.top.equalTo(_topView.mas_bottom);
        make.height.equalTo(_topView.mas_height);
    }];
    
    [_topView addSubview:_topInnerView];
    [_topInnerView makeConstraints:^(MASConstraintMaker *make) {
        make.width.equalTo(_topInnerView.mas_height).multipliedBy(3);
        make.center.equalTo(_topView);
        make.width.and.height.lessThanOrEqualTo(_topView);
        make.width.and.height.equalTo(_topView).priorityLow();
    }];
    
    [_bottomView addSubview:_bottomInnerView];
    [_bottomInnerView makeConstraints:^(MASConstraintMaker *make) {
        make.height.equalTo(_bottomInnerView.mas_width).multipliedBy(3);
        make.center.equalTo(_bottomView);
        make.width.and.height.lessThanOrEqualTo(_bottomView);
        make.width.and.height.equalTo(_bottomView).priorityLow();
    }];

PS:設置約束的時候兩個視圖要在同一父視圖上或者有關系

簡單動畫

MASExampleAnimatedView

- (void)makeConstraints {
    int padding = self.padding;
    UIEdgeInsets paddingInserts = UIEdgeInsetsMake(padding, padding, padding, padding);
    
    [self.greenView makeConstraints:^(MASConstraintMaker *make) {
        [self.animateArray addObjectsFromArray:@[
            make.edges.equalTo(self).offset(paddingInserts).priorityLow(),
            make.right.equalTo(self.redView.mas_left).offset(-padding),
            make.bottom.equalTo(self.blueView.mas_top).offset(-padding)
            ]
         ];
        make.size.equalTo(self.redView);
        make.height.equalTo(self.blueView);
    }];
    
    [self.redView makeConstraints:^(MASConstraintMaker *make) {
        [self.animateArray addObjectsFromArray:@[
            make.edges.equalTo(self).offset(paddingInserts).priorityLow(),
            make.bottom.equalTo(self.blueView.mas_top).offset(-padding)
            ]
         ];
    }];
    
    [self.blueView makeConstraints:^(MASConstraintMaker *make) {
        [self.animateArray addObject:make.edges.equalTo(self).offset(paddingInserts).priorityLow()];
    }];
}
// 移動到window顯示的時候開始動畫
- (void)didMoveToWindow {
    [self layoutIfNeeded];
    
    if (self.window) {
        self.isAnimating = YES;
        [self anmateWithInvertedInserts:NO];
    }
}

- (void)willMoveToWindow:(UIWindow *)newWindow {
    self.isAnimating = newWindow != nil;
}

- (void)anmateWithInvertedInserts:(BOOL)invertedInserts {
    if (!self.isAnimating) {
        return;
    }
    int padding = invertedInserts ? 100 : self.padding;
    UIEdgeInsets paddingInserts = UIEdgeInsetsMake(padding, padding, padding, padding);
    // 遍歷之前存儲的約束柏腻、依次修改
    for (MASConstraint *constraint in self.animateArray) {
        constraint.insets = paddingInserts;
    }
    // 使用動畫更新視圖
    [UIView animateWithDuration:1.0 animations:^{
        [self layoutIfNeeded];
    } completion:^(BOOL finished) {
        [self anmateWithInvertedInserts:!invertedInserts];
    }];
}

長文本約束

MASExampleLabelView

主要存在兩種情況
1.右邊短文本势就,左邊長文本辞居。
重寫layoutSubviews方法確定短文本寬度,由此確定長文本寬度蛋勺,設置preferredMaxLayoutWidth
左邊短文本,右邊長文本鸠删。與上面一樣處理

[self.longLabel makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(self.left).insets(kPadding);
    make.top.equalTo(self.top).insets(kPadding);
}];

[self.shortLabel makeConstraints:^(MASConstraintMaker *make) {
     make.centerY.equalTo(self.longLabel.centerY);
    make.right.equalTo(self.right).insets(kPadding);
}];
    
- (void)layoutSubviews {
    [super layoutSubviews];
    // 使用Autolayout抱完,由此方法獲取真實的frame
    CGFloat width = CGRectGetMinX(self.shortLabel.frame) - kPadding.left;
    width -= CGRectGetMinX(self.longLabel.frame);
    self.longLabel.preferredMaxLayoutWidth = width;

    //再次調(diào)用,重新計算
    [super layoutSubviews];
}

2.上面長文本刃泡,下面固定

- (void)makeConstraints {
    UIView *superView = self;
    [self.longLabel makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(superView.top).offset(kPadding);
        make.left.equalTo(superView.left).offset(kPadding);
        make.right.equalTo(superView.right).offset(-kPadding);
        make.bottom.equalTo(self.shortLabel.top).offset(-kPadding);
    }];
    
    [self.shortLabel makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(superView).offset(kInserts).priorityLow();
        make.left.equalTo(superView.left).offset(kPadding);
    }];
}

ScrollView

ScrollView的約束一般是在其上面添加一個contentView通過約束這個contentView來達到效果

- (void)generateContent {
    UIView* contentView = UIView.new;
    [self.scrollView addSubview:contentView];
    
    [contentView makeConstraints:^(MASConstraintMaker *make) {
        // 上下左右與scrollView間距為0巧娱,寬度相同,垂直滾動的scrollView必須確定寬度
        make.edges.equalTo(self.scrollView);
        make.width.equalTo(self.scrollView);
    }];
    // 開始計算contentView的高度
    UIView *lastView;
    CGFloat height = 25;
    
    for (int i = 0; i < 10; i++) {
        UIView *view = UIView.new;
        view.backgroundColor = [self randomColor];
        [contentView addSubview:view];
        
        UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
        [view addGestureRecognizer:singleTap];
        
        [view mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(lastView ? lastView.bottom : @0);
            make.left.equalTo(@0);
            make.width.equalTo(contentView.width);
            make.height.equalTo(@(height));
        }];
        
        height += 25;
        lastView = view;
    }
    
    [contentView makeConstraints:^(MASConstraintMaker *make) {
        // 對contentView高度進行約束
        make.bottom.equalTo(lastView.bottom);
    }];
}

Array

多個view對齊的約束

- (void)updateConstraints {
    [self.buttonViews updateConstraints:^(MASConstraintMaker *make) {
        // 添加baseline對齊
        make.baseline.equalTo(self.mas_centerY).with.offset(self.offset);
    }];
    
    //最后才調(diào)用
    [super updateConstraints];
}

AttributeChaining

鏈式語法

    [greenView mas_makeConstraints:^(MASConstraintMaker *make) {
        // chain attributes
        make.top.and.left.equalTo(superview).insets(padding);

        // 相當于
//        make.top.greaterThanOrEqualTo(superview).insets(padding);
//        make.left.greaterThanOrEqualTo(superview).insets(padding);

        make.bottom.equalTo(blueView.mas_top).insets(padding);
        make.right.equalTo(redView.mas_left).insets(padding);
        make.width.equalTo(redView.mas_width);

        make.height.equalTo(@[redView, blueView]);
    }];

間距

利用預先設定好的間距布局

        view.layoutMargins = UIEdgeInsetsMake(5, 10, 15, 20);
        [self addSubview:view];
        
        [view mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(lastView.topMargin);
            make.bottom.equalTo(lastView.bottomMargin);
            make.left.equalTo(lastView.leftMargin);
            make.right.equalTo(lastView.rightMargin);
        }];

多個控件固定間隔的等間隔排列

MASExampleDistributeView

/**
 *  多個控件固定間隔的等間隔排列,變化的是控件的長度或者寬度值
 *
 *  @param axisType        軸線方向
 *  @param fixedSpacing    間隔大小
 *  @param leadSpacing     頭部間隔
 *  @param tailSpacing     尾部間隔
 */
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType 
                    withFixedSpacing:(CGFloat)fixedSpacing l
                          eadSpacing:(CGFloat)leadSpacing 
                         tailSpacing:(CGFloat)tailSpacing;

/**
 *  多個固定大小的控件的等間隔排列,變化的是間隔的空隙
 *
 *  @param axisType        軸線方向
 *  @param fixedItemLength 每個控件的固定長度或者寬度值
 *  @param leadSpacing     頭部間隔
 *  @param tailSpacing     尾部間隔
 */
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType 
                 withFixedItemLength:(CGFloat)fixedItemLength 
                         leadSpacing:(CGFloat)leadSpacing 
                         tailSpacing:(CGFloat)tailSpacing;

LayoutGuide

MASExampleLayoutGuideViewController

    [topView makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.mas_topLayoutGuide);
        make.left.equalTo(self.view);
        make.right.equalTo(self.view);
        make.height.equalTo(@40);
    }];

    [topSubview makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.mas_topLayoutGuide);
        make.centerX.equalTo(@0);
        make.width.equalTo(@20);
        make.height.equalTo(@20);
    }];
    
    [bottomView makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.mas_bottomLayoutGuide);
        make.left.equalTo(self.view);
        make.right.equalTo(self.view);
        make.height.equalTo(@40);
    }];
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烘贴,一起剝皮案震驚了整個濱河市禁添,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桨踪,老刑警劉巖老翘,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锻离,居然都是意外死亡铺峭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門汽纠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卫键,“玉大人,你說我怎么就攤上這事虱朵±蚵” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵碴犬,是天一觀的道長絮宁。 經(jīng)常有香客問我,道長服协,這世上最難降的妖魔是什么羞福? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮蚯涮,結果婚禮上治专,老公的妹妹穿的比我還像新娘卖陵。我一直安慰自己,他們只是感情好张峰,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布泪蔫。 她就那樣靜靜地躺著,像睡著了一般喘批。 火紅的嫁衣襯著肌膚如雪撩荣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天饶深,我揣著相機與錄音餐曹,去河邊找鬼。 笑死敌厘,一個胖子當著我的面吹牛台猴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俱两,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饱狂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了宪彩?” 一聲冷哼從身側響起休讳,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尿孔,沒想到半個月后俊柔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡活合,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年婆咸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芜辕。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡尚骄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侵续,到底是詐尸還是另有隱情倔丈,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布状蜗,位于F島的核電站需五,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏轧坎。R本人自食惡果不足惜宏邮,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜜氨,春花似錦械筛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至郎汪,卻和暖如春赤赊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背煞赢。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工抛计, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人照筑。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓吹截,卻偏偏與公主長得像,于是被迫代替她去往敵國和親朦肘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容