Masonry框架學(xué)習(xí)

Masonry

使用

  • 關(guān)鍵方法:- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
  • 約束方法除了equalTo,還有l(wèi)essThanOrEqualTo和greaterThanOrEqualTo
  • 當(dāng)已有約束需要更新時(shí)調(diào)用mas_updateConstraints方法
  • mas_remakeConstraints方法會(huì)先清除當(dāng)前所有約束再布置
  • Masonry的五大參數(shù):Attribute(屬性) ,Relation(關(guān)系),Multiplier(乘),Constant(大小),Priority(優(yōu)先級(jí))
    //一個(gè)系統(tǒng)的約束創(chuàng)建方法
    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:padding.top]
                                  
    //mas_makeConstraints
    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(superView).with.offset(10);
        make.left.equalTo(superView).with.offset(10);
        make.bottom.equalTo(superView.mas_bottom).with.offset(-10);
        make.right.equalTo(superView.mas_right).with.offset(-10);
//        等價(jià)于
//        make.edges.equalTo(superView).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
//        會(huì)自動(dòng)調(diào)用view1.translatesAutoresizingMaskIntoConstraints = NO;
    }];
    //mas_remakeConstrains
    [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);
        }
    }];
    //mas_updateConstraints
        [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self);
        make.width.equalTo(@(self.buttonSize.width)).priorityLow();
        make.height.equalTo(@(self.buttonSize.height)).priorityLow();
        make.width.lessThanOrEqualTo(self);
        make.height.lessThanOrEqualTo(self);
    }];

    //according to apple super should be called at end of method
    [super updateConstraints];
}

原理

  • mas_makeConstraints方法內(nèi)部創(chuàng)建MASConstraintMaker對(duì)象,然后傳遞到block執(zhí)行,完成后調(diào)用maker的install方法來(lái)確保約束被添加到視圖中
//設(shè)置約束方法
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block {
    self.translatesAutoresizingMaskIntoConstraints = NO;
    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
    constraintMaker.updateExisting = YES;
    block(constraintMaker);
    return [constraintMaker install];
}
//MASConstraintMaker的install方法
- (NSArray *)install {
    //判斷是否有移除所有已存在的約束標(biāo)志
    if (self.removeExisting) {
        NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view];
        for (MASConstraint *constraint in installedConstraints) {
            [constraint uninstall];
        }
    }
    //取出maker對(duì)象中的所有約束
    NSArray *constraints = self.constraints.copy;
    for (MASConstraint *constraint in constraints) {
    //設(shè)置已經(jīng)設(shè)置了約束的標(biāo)志
        constraint.updateExisting = self.updateExisting;
        //調(diào)用MASConstraint的install方法
        [constraint install];
    }
    [self.constraints removeAllObjects];
    return constraints;
}
//MASViewConstraint(MASConstraint子類(lèi))的install方法
- (void)install {
    ...
    ...
    MASLayoutConstraint *layoutConstraint
        = [MASLayoutConstraint constraintWithItem:firstLayoutItem
                                        attribute:firstLayoutAttribute
                                        relatedBy:self.layoutRelation
                                           toItem:secondLayoutItem
                                        attribute:secondLayoutAttribute
                                       multiplier:self.layoutMultiplier
                                         constant:self.layoutConstant];
    
    ...
    ...
    MASLayoutConstraint *existingConstraint = nil;
    if (self.updateExisting) {
        existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint];
    }
    if (existingConstraint) {
        // just update the constant
        existingConstraint.constant = layoutConstraint.constant;
        self.layoutConstraint = existingConstraint;
    } else {
        //調(diào)用系統(tǒng)方法添加約束
        [self.installedView addConstraint:layoutConstraint];
        self.layoutConstraint = layoutConstraint;
        [firstLayoutItem.mas_installedConstraints addObject:self];
    }
}

MASConstraint和其子類(lèi)

  • MASConstraint提供了基礎(chǔ)屬性(left,top,leftMargin...),且是創(chuàng)建鏈?zhǔn)秸Z(yǔ)法的必要要素
  • MASCompositeConstraint內(nèi)有一個(gè)childConstraints的屬性,在布局的時(shí)候,會(huì)遍歷該數(shù)組,逐一進(jìn)行install方法調(diào)用,make.edges,make.size返回的就是該類(lèi)型
  • MASViewConstraint是承載支持AutoLayout真正的對(duì)象,他創(chuàng)建了一個(gè)NSLayoutConstraint的必要屬性,并將其添加到對(duì)應(yīng)的view上;它的firstViewAttribute和secondViewAttribute屬性分別代表了對(duì)應(yīng)要設(shè)置約束兩個(gè)view的屬性

Masonry鏈?zhǔn)秸Z(yǔ)法實(shí)現(xiàn)原理

進(jìn)入文件中可發(fā)現(xiàn)left,top..等maker屬性方法返回都是MASConstraint類(lèi)型,而MASConstraint中也有這些相同的屬性方法,返回值依是MASCompositeConstraint對(duì)象,所有才能像make.top.left.right...這樣使用Masonry,具體實(shí)現(xiàn)原理如下

 1利诺、MASConstraint的left方法:

    - (MASConstraint *)left {
        return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
    }
    它會(huì)跳轉(zhuǎn)到MASViewConstraint的addConstraintWithLayout...方法
--------------------------------------------    
    2糙箍、MASViewConstraint的addConstraintWithLayout...方法

    - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
        return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
    }
    它會(huì)調(diào)用delegate的constraint...delegate就是MASConstraintMaker销凑,來(lái)看看吧
--------------------------------------------
    3、MASConstraintMaker的代理方法

    - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
            MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
            [self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint];
            return compositeConstraint;
    }
    創(chuàng)建的compositeConstraint布局時(shí),就會(huì)調(diào)用children的install方法設(shè)置約束,從而達(dá)到通過(guò)點(diǎn)語(yǔ)法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唤蔗,一起剝皮案震驚了整個(gè)濱河市钥星,隨后出現(xiàn)的幾起案子控汉,更是在濱河造成了極大的恐慌,老刑警劉巖腥沽,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異崩哩,居然都是意外死亡巡球,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)邓嘹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)酣栈,“玉大人,你說(shuō)我怎么就攤上這事汹押】篌荩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵棚贾,是天一觀的道長(zhǎng)窖维。 經(jīng)常有香客問(wèn)我榆综,道長(zhǎng),這世上最難降的妖魔是什么铸史? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任鼻疮,我火速辦了婚禮,結(jié)果婚禮上琳轿,老公的妹妹穿的比我還像新娘判沟。我一直安慰自己,他們只是感情好崭篡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布挪哄。 她就那樣靜靜地躺著,像睡著了一般琉闪。 火紅的嫁衣襯著肌膚如雪迹炼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天颠毙,我揣著相機(jī)與錄音斯入,去河邊找鬼。 笑死吟秩,一個(gè)胖子當(dāng)著我的面吹牛咱扣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涵防,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闹伪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了壮池?” 一聲冷哼從身側(cè)響起偏瓤,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎椰憋,沒(méi)想到半個(gè)月后厅克,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡橙依,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年证舟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窗骑。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡女责,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出创译,到底是詐尸還是另有隱情抵知,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站刷喜,受9級(jí)特大地震影響残制,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掖疮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一初茶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浊闪,春花似錦纺蛆、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)温峭。三九已至猛铅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凤藏,已是汗流浹背奸忽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揖庄,地道東北人栗菜。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蹄梢,于是被迫代替她去往敵國(guó)和親疙筹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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