Masonry是iOS在控件布局中經(jīng)常使用的一個輕量級框架啡省,Masonry讓NSLayoutConstraint使用起來更為簡潔依啰。Masonry簡化了NSLayoutConstraint的使用方式顷蟆,讓我們可以以鏈?zhǔn)降姆绞綖槲覀兊目丶付s束踩官。本篇博客的主題不是教你如何去使用Masonry框架的吆豹,而是對Masonry框架的源碼進行解析哎媚,讓你明白Masonry是如何對NSLayoutConstraint進行封裝的租漂,以及Masonry框架中的各個部分所扮演的角色是什么樣的阶女。在Masonry框架中,仔細的品味干貨還是很多的哩治。Masonry框架是Objective-C版本的秃踩,如果你的項目是Swift語言的,那么就得使用SnapKit布局框架了业筏。SnapKit其實就是Masonry的Swift版本憔杨,兩者雖然實現(xiàn)語言不同,但是實現(xiàn)思路大體一致蒜胖。
今天博客對Masonry框架源碼的解析思路是先對比給一個View添加同樣的約束時消别,使用Masonry與系統(tǒng)原生的區(qū)別。然后就開門見山之間給出Masonry框架主要部分的類圖台谢,從類圖中我們來整體的分析Masonry框架的結(jié)構(gòu)寻狂。然后再由整體到部分逐漸的細化,窺探其內(nèi)部的實現(xiàn)細節(jié)朋沮。通過上述步驟蛇券,我們將對Masonry框架的內(nèi)部實現(xiàn)進行詳細的了解。其實Masonry框架是輕量級的樊拓,總共的源碼也沒有多上行怀读,但是仔細的閱讀其實現(xiàn)細節(jié),還是可以吸取很多實用的東西的骑脱。
首先Masonry在github上的地址是https://github.com/SnapKit/Masonry, 你可以通過上述鏈接Clone到Masonry框架,其中有Masonry框架介紹以及一些Masonry的使用示例苍糠。關(guān)于Masonry的使用方式在今天的博客中就不做過多的贅述了叁丧,其具體的使用方式請參考上述github上的鏈接。今天我們就剖析一下Masonry框架的源碼岳瞭。
一拥娄、Masonry框架與NSLayoutConstraint調(diào)用方式的對比
首先我們NSLayoutConstraint為我們的View添加一個約束,然后再給出Masonry的代碼瞳筏。當(dāng)然在此我們就不說Masonry添加約束的簡潔行了稚瘾,當(dāng)然好東西是不需要宣傳的。進入該部分的主題姚炕,我們要對一個View添加一個top約束摊欠,這個約束關(guān)系我們用表達式來表示就是“subView.top = superView.top + 10”丢烘。也就是子視圖的top與父視圖的top中間隔著10個pt。
1. 使用NSLayoutConstraint添加約束
下方這段代碼就是給subView添加了一個相對于superView的Top約束些椒。一個View要想確定位置一個約束是不夠的播瞳,所以可想而知,我們要寫多個下方的這樣的約束來確定一個View的相對位置免糕。其實下方就是一個表達式赢乓,NSLayoutConstraint構(gòu)造器中每個參數(shù)構(gòu)成這個表達式的一個組成部分。由上到下我們隊參數(shù)個個參數(shù)進行解析石窑,參數(shù)constraintWithItem用來指定所約束的對象牌芋,在此就是subView。第一個attribute參數(shù)則指定約束該對象的那個屬性松逊,在此就是subView的Top屬性躺屁。參數(shù)relatedBy用來指定約束關(guān)系,比如大于等于棺棵,小于等于或者等于某個約束值楼咳。參數(shù)toItem則指定的是約束相對的對象,在此是相對superView的烛恤,所以此處的參數(shù)是superView母怜。第二個attribute參數(shù)就是指定superView的Top屬性。multiplier指定相對約束的倍數(shù)關(guān)系缚柏,constant則是約束的偏移量苹熏。
由上到下,NSLayoutConstraint的構(gòu)造器中的參數(shù)會構(gòu)成一個數(shù)學(xué)表達式币喧,那就是subView.top = superView.top * 1 + 10轨域,該表達式就直觀的給出了subView.top與superView.top的關(guān)系。經(jīng)下方的代碼我們就為subView添加了一個相對于superView的Top約束杀餐,約束的偏移量是10干发。
2.使用Masonry添加上述約束
接下來就是Masonry出場的時刻了,我們將使用Masonry添加上述約束史翘,其代碼如下枉长。下方給出了三種設(shè)置方式,下方三種方式是等價的琼讽,當(dāng)然在Masonry中不知下方三種實現(xiàn)方式必峰。下方Block中的每句話都代表著subView.top = superView.top * 1 + 10的意思,也就是說我們只需要寫這三行代碼中的其中一種即可钻蹬。使用Masonry的好處一目了然吼蚁,讓你的代碼更為簡潔。
Masonry框架中支持約束的添加问欠,約束的更新肝匆,約束的重建以及基本動畫的實現(xiàn)等等粒蜈。功能還是蠻強大的。在Masonry框架主要中采用了鏈?zhǔn)秸{(diào)用和匿名閉包的方式來簡化約束的添加术唬。有關(guān)Masonry更為詳細的使用方式請參見上述Masonry框架的Github鏈接薪伏,具體使用方式在此就不做過多的贅述了。
二粗仓、Masonry框架的類結(jié)構(gòu)
通過上述的Masonry的使用方式我們可以看出嫁怀,UIView的對象可以直接調(diào)用mas_makeConstraints方法來為相應(yīng)的View對象添加約束。因為mas_makeConstraints方法位于UIView的View+MASAdditions類目中借浊,所以UIView的對象可以直接調(diào)用塘淑。同樣在View+MASAdditions類目還有其他方法供UIView的對象使用,稍后會進行詳細的介紹蚂斤。
下方就是Masonry框架核心類以及類目之間的關(guān)系存捺,下方的類圖是在閱讀Masonry源碼時畫的,僅此一份曙蒸,如有雷同純屬巧合捌治。如果下圖中的文字比較小的話,你可以圖片另存到本地纽窟,然后放大后進行查看肖油,廢話少說,進入我們類圖的主題臂港。下方的類圖中沒有包括Masonry框架中的所有的類森枪,不過所有核心的類都在下方了。我們從左往右依次對下方的類圖進行解說审孽。
1.View+MASAdditions類目介紹(左邊紅框中的部分)
最左邊那一坨大類县袱,也就是綠框中的部分,就是Masonry框架對UIView的公有類目佑力,也就是源文件中的View+MASAdditions的部分式散,在該類目中為添加了類型為MASViewAttribute的成員屬性(稍后會介紹MASViewAttribute是個神馬東西)。除了添加一系列的成員屬性外打颤,還添加了四個公有的方法:mas_closestCommonSuperview方法負責(zé)尋找兩個視圖的最近的公共父視圖(類比兩個數(shù)字的最小公倍數(shù))杂数、mas_makeConstraints方法負責(zé)創(chuàng)建安裝約束、mas_updateConstraints負責(zé)更新已經(jīng)存在的約束(若約束不存在就Install)瘸洛、mas_remakeConstraints方法則負責(zé)移除原來已經(jīng)創(chuàng)建的約束并添加上新的約束。上述方式是UIView對象設(shè)置約束主要調(diào)用的方法次和,稍后會詳細介紹其實現(xiàn)方式反肋。
2.MASViewAttribute類的介紹(右邊黃框中的部分)
介紹完用戶直接使用的UIView的公共類目,接下來我們來看一下用戶看不到的部分踏施,那就是下方類圖中右邊的那一撮類石蔗。右邊的四個小類的耦合性比較高罕邀,我們先看一下MASViewAttribute類。MASViewAttribute類的結(jié)構(gòu)比較簡單养距,主要包括三個屬性诉探,三個方法。從MASViewAttribute這個類名中我們就能看出棍厌,這個類是對UIView和NSLayoutAttribute的封裝肾胯。使用等式來表示就是MASViewAttribute = UIView + NSLayoutAttribute + item。在MASViewAttribute類中的view屬性表示所約束的對象耘纱,而item就是該對象上可以被約束的部分敬肚。
此處的item成員屬性我們稍后要作為NSLayoutConstriant構(gòu)造器中的constraintWithItem與toItem的參數(shù)。當(dāng)然對于UIView來說該item就是UIView本身束析。而對于UIViewController艳馒,該出Item就topLayoutGuide,bottomLayoutGuide稍后會給出詳細的介紹员寇。該類中除了兩個構(gòu)造器外還有一個isSizeAttribute方法弄慰,該方法用來判斷MASViewAttribute類中的layoutAttribute屬性是否是NSLayoutAttributeWidth或者NSLayoutAttributeHeight,如果是Width或者Height的話蝶锋,那么約束就添加到當(dāng)前View上陆爽,而不是添加在父視圖上。
3.MASViewConstraint的介紹(右邊黃框中的部分)
接著我們看一下MASViewConstraint類牲览,該類是對NSLayoutConstriant類的進一步封裝墓陈。MASViewConstraint做的最核心的一件事情就是初始化NSLayoutConstriant對象,并將該對象添加在相應(yīng)的視圖上第献。因為NSLayoutConstriant在初始化時需要NSLayoutAttribute和所約束的View贡必,而MASViewAttribute正是對View與NSLayoutAttribute進行的封裝,所以MASViewConstraint類要依賴于MASViewAttribute類庸毫,兩者的關(guān)系如下所示仔拟。
由下方的類圖我們可以看出MASConstraint是MASViewConstraint的父類,MASConstraint是一個抽象類飒赃,不可被實例化利花。我們可以將MASConstraint看做是一個接口或者協(xié)議。MASConstraint抽象類還有一個子類载佳,也就是MASViewConstraint的兄弟類MASCompositeConstraint炒事,從MASCompositeConstraint的命名中我們就可以看出來MASCompositeConstraint是約束的一個組合,也就是其中存儲的是一系列的約束蔫慧。MASCompositeConstraint類的結(jié)構(gòu)比較簡單挠乳,其核心就是一個存儲MASViewConstraint對象的數(shù)組,MASCompositeConstraint就是對該數(shù)組的一個封裝而已。
4.工廠類MASConstraintMaker(中間綠框中的部分)
兩邊的看完了睡扬,接下來我們來看一下中間的部分盟蚣,也就是MASConstraintMaker類。該類就是一個工廠類卖怜,負責(zé)創(chuàng)建MASConstraint類型的對象(依賴于MASConstraint接口屎开,而不依賴于具體實現(xiàn))。在UIView的View+MASAdditions類目中就是調(diào)用的MASConstraintMaker類中的一些方法马靠。上述我們在使用Masonry給subView添加約束時奄抽,mas_makeConstraints方法中的Block的參數(shù)就是MASConstraintMaker的對象。用戶可以通過該Block回調(diào)過來的MASConstraintMaker對象給View指定要添加的約束以及該約束的值虑粥。該工廠中的constraints屬性數(shù)組就記錄了該工廠創(chuàng)建的所有MASConstraint對象如孝。
Masonry框架中的核心類以及類目間的關(guān)系就介紹完了,下方就是核心類和類目的類圖娩贷。下方將會逐步的窺探其代碼實現(xiàn)第晰。
三、View+MASAdditions源碼解析
我們先對UIView的公共類目View+MASAdditions中的源碼進行解析彬祖,也就是對應(yīng)著上方紅框中的部分茁瘦。用戶是通過 View+MASAdditions中的東西來為View添加約束的,View+MASAdditions也就是Masonry框架與外界交互的通道储笑。該部分主要對View+MASAdditions源碼進行解析甜熔,先介紹其成員屬性,然后介紹主要的方法突倍。進入該部分的主題腔稀。
1.View+MASAdditions主要成員屬性及getter方法
下方截圖中是View+MASAdditions類目中的部分成員屬性,其他的也與下方類似羽历,這些屬性都是MASViewAttribute類型的焊虏。以下方的mas_left成員屬性為例,因為MASViewAttribute是View與NSLayoutAttribute的合體秕磷,所以mas_left就代表著當(dāng)前View的NSLayoutAttributeLeft屬性诵闭,也就是mas_left存儲的是當(dāng)前View的NSLayoutAttributeLeft屬性。同理澎嚣,mas_top就代表著當(dāng)前View的NSLayoutAttributeTop屬性疏尿,其他成員屬性也是一樣。
通過上述成員屬性所對應(yīng)的getter方法易桃,我們可以對其中所存儲的內(nèi)容一目了然褥琐。下方是mas_left、mas_top和mas_right成員屬性所對應(yīng)的getter方法晤郑,其中所做的事情就是對MASViewAttibute進行實例化踩衩,在實例化時指定當(dāng)前視圖所對應(yīng)的LayoutAttribute嚼鹉。也就是mas_left = self + NSLayoutAttributeLeft, mas_top = self +NSLayoutAttributeTop, 當(dāng)然此處的self就代表當(dāng)前視圖。
2.mas_makeConstraints方法解析
上面在介紹類圖的時候也提到了驱富,用戶是通過調(diào)用mas_makeConstraints方法來為當(dāng)前視圖添加約束的。下方代碼就是mas_makeConstraints函數(shù)的代碼實現(xiàn)匹舞,根據(jù)個人理解褐鸥,對每行代碼進行了中文注釋,接下來我們來好好的看一下該函數(shù)的結(jié)構(gòu).mas_makeConstraints方法的返回值是一個數(shù)組(NSArray),數(shù)組中所存放的就是當(dāng)前視圖中所添加的所有約束。因為Masonry框架對NSLayoutConstraint封裝成了MASViewConstraint赐稽,所有此處數(shù)組中存儲的是MASViewConstraint對象叫榕。
接下來來看mas_makeConstraints的參數(shù),mas_makeConstraints測參數(shù)是一個類型為void(^)(MASConstraintMaker *)的匿名Block(也就是匿名閉包)姊舵,該閉包的返回值為Void, 并且需要一個MASConstraintMaker工廠類的一個對象晰绎。該閉包的作用就是可以讓mas_makeConstraints方法通過該block給MASConstraintMaker工廠類對象中的MAConstraint屬性進行初始化。請參加下方block的使用括丁。
在mas_makeConstraints方法體中荞下,首先將當(dāng)前View的translatesAutoresizingMaskIntoConstraints屬性設(shè)置成No, 然后創(chuàng)建了一個MASConstraintMaker工廠類對象constraintMaker,然后通過block將constraintMaker對象回調(diào)給用戶讓用戶對constraintMaker中的MAConstraint類型的屬性進行初始化史飞。換句話說block中所做的事情就是之前用戶設(shè)置約束是所添加的代碼尖昏,比如make.top(@10) == ( constraintMaker.top = 10 )。最后調(diào)用constraintMaker的install方法對用戶指定的約束進行安裝构资。
3.mas_updateConstraints與mas_remakeConstraints函數(shù)的解析
這兩個函數(shù)內(nèi)部的實現(xiàn)與mas_makeConstraints類似抽诉,就是多了一個屬性的設(shè)置。mas_updateConstraints中將constraintMaker中的updateExisting設(shè)置為YES, 也就是說當(dāng)添加約束時要先檢查約束是否已經(jīng)被安裝了吐绵,如果被添加了就更新迹淌,如果沒有被添加就添加。而mas_remakeConstraints中所做的事情是將removeExisting屬性設(shè)置成YES, 表示將當(dāng)前視圖上的舊約束進行移除己单,然后添加上新的約束唉窃。
4、mas_closestCommonSuperview方法解析
mas_closestCommonSuperview方法負責(zé)計算出兩個視圖的公共父視圖荷鼠,這個類似求兩個數(shù)字的最小公倍數(shù)句携。下方的代碼就是尋找兩個視圖的公共父視圖,當(dāng)然是最近的那個公共父視圖允乐。如果找到了就返回矮嫉,如果找不到就返回nil。尋找兩個視圖的公共父視圖對于約束的添加來說是非常重要的牍疏,因為相對的約束是添加到其公共父視圖上的蠢笋。比如舉個列子 viewA.left = viewB.right + 10, 因為是viewA與viewB的相對約束,那么約束是添加在viewA與viewB的公共父視圖上的鳞陨,如果viewB是viewA的父視圖昨寞,那么約束就添加在viewB上從而對viewA起到約束作用瞻惋。
四、順藤摸瓜援岩,解析約束工廠類MASConstraintMaker
上一個部分我們分析了View+MASAdditions類目歼狼,在該類目中主要使用到了約束的工廠類MASConstraintMaker,接下我們就來窺探一下MASConstraintMaker中的內(nèi)容享怀。MASConstraintMaker之所以成為約束工廠類羽峰,因為MASConstraintMaker賦值創(chuàng)建NSLayoutConstraint對象,因為Masonry將NSLayoutConstraint類進一步封裝成了MASViewConstraint添瓷,所以MASConstraintMaker是負責(zé)創(chuàng)建MASViewConstraint的對象梅屉,并調(diào)用MASViewConstraint對象的Install方法將該約束添加到相應(yīng)的視圖中。
1.MASConstraintMaker中的核心公有屬性鳞贷。
下方截圖是MASConstraintMaker中的部分屬性坯汤,可以看出下方的屬性都是MSAConstriant類型,MSAConstriant是抽象類搀愧,所以下方成員變量存儲的實質(zhì)上是MSAConstriant子類MASViewConstraint的對象惰聂。MASConstraintMaker就負責(zé)對MASViewConstraint進行實例化。一句話解釋MASViewConstraint妈橄,MASViewConstraint = View + NSLayoutConstraint + Install庶近。稍后會給出MASViewConstraint具體技術(shù)細節(jié)的實現(xiàn)。在MASConstraintMaker還有一個私有數(shù)組constraints眷蚓,該數(shù)組就用來記錄以及創(chuàng)建的Constraint對象鼻种。
2.MASConstraintMake中的工廠方法解析
工廠類肯定有工廠方法,接下來我們來介紹MASConstraintMaker中的工廠方法方法沙热,上面每個MASConstraint類型的屬性都對應(yīng)一個getter方法叉钥,在getter方法中都會調(diào)用addConstraintWithLayoutAttribute方法,而addConstraintWithLayoutAttribute會調(diào)用第二個截個圖中的方法篙贸,而截圖中的這個方法就是MASConstraintMaker工廠類的工廠方法投队,根據(jù)提供的參數(shù)創(chuàng)建MSAViewConstraint對象,如果該函數(shù)的第一個參數(shù)不為空的話就會將新創(chuàng)建的MSAViewConstraint對象與參數(shù)進行合并組合成MASCompositeConstraint類(MASCompositeConstraint本質(zhì)上是MSAViewConstraint對象的數(shù)組)的對象爵川。
下方就是MASConstraintMaker工廠類的工廠方法敷鸦,負責(zé)創(chuàng)建MASConstraint類的對象。下方的方法可以創(chuàng)建MASCompositeConstraint和MASViewConstraint對象寝贡,上面也說了扒披,MASCompositeConstraint對象就是MASViewConstraint對象的數(shù)組。下方創(chuàng)建完MASConstraint類的相應(yīng)的對象后圃泡,會把該創(chuàng)建的對象添加進MASConstraintMaker工廠類的私有constraints數(shù)組碟案,來記錄該工廠對象創(chuàng)建的所有約束。newConstraint.delegate = self; 這句話是非常重要的颇蜡,由于為MASConstraint對象設(shè)置了代理价说,所以才支持鏈?zhǔn)秸{(diào)用(例如:maker.top.left.right.equalTo(@10))辆亏。
關(guān)于鏈?zhǔn)秸{(diào)用咱就以maker.top.left.right為例。此處的maker, 就是我們的MASConstraintMaker工廠對象鳖目,maker.top會返回帶有NSLayoutAttributeTop屬性的MASViewConstraint類的對象扮叨,我們先做一個轉(zhuǎn)換:newConstraint = maker.top。那么maker.top.left 等價于newConstraint.left领迈,需要注意的是此刻調(diào)用的left方法就不在是我們工廠MASConstraintMaker中的left的getter方法了甫匹,而是被換到MASViewConstraint類中的left屬性的getter方法了。給newConstraint設(shè)置代理就是為了可以在MASViewConstraint類中通過代理來調(diào)用MASConstraintMaker工廠類的工廠方法來完成創(chuàng)建惦费。下方代碼如果沒有newConstraint.delegate = self;代理的設(shè)置的話,那就不支持鏈?zhǔn)秸{(diào)用抢韭。
說了這么多薪贫,總結(jié)一下,如果你調(diào)用maker.top, maker.left等等這些方法都會調(diào)用下方的工廠方法來創(chuàng)建相應(yīng)的MASViewConstraint對象刻恭,并記錄在工廠對象的約束數(shù)組中瞧省。之所以能鏈?zhǔn)秸{(diào)用,就是講當(dāng)前的工廠對象指定為MASViewConstraint對象的代理鳍贾,所以一個MASViewConstraint對象就可以通過代理來調(diào)用工廠方法來創(chuàng)建另一個新的MASViewConstraint對象了鞍匾,此處用到了代理模式。
3. 工廠類中的install方法
雖然我們將MASConstraintMake視為工廠類骑科,不過該工廠類的功能不僅僅創(chuàng)建MASConstraint的對象橡淑,還負責(zé)調(diào)用MASConstraint對象的install方法來將相應(yīng)的約束安裝到想要的視圖上。在MASConstraintMake類中的install方法就是遍歷工廠對象所創(chuàng)建所有約束對象并調(diào)用每個約束對象的install方法來進行約束的安裝咆爽。下方就是該工廠類中的install方法梁棠。
在安裝約束時,如果self.removeExisting == Yes, 那么用戶就通過mas_remakeConstraints方法調(diào)用的install方法斗埂,就先將原來的約束進行移除掉符糊,然后添加上新的約束。在安裝約束時呛凶,將updateExisting賦值給每個約束男娄,每個約束在調(diào)用本身的install方法時會判斷是否更新。下方就是MASConstraintMake的install方法的實現(xiàn)和注釋漾稀。
五模闲、繼續(xù)順藤摸瓜,解析MASViewConstraint
MASConstraintMaker工廠類所創(chuàng)建的對象實質(zhì)上是MASViewConstraint類的對象县好。而MASViewConstraint類實質(zhì)上是對MASLayoutConstraint的封裝围橡,進一步說MASViewConstraint負責(zé)為MASLayoutConstraint構(gòu)造器組織參數(shù)并創(chuàng)建MASLayoutConstraint的對象,并將該對象添加到相應(yīng)的視圖中缕贡。接下來我們將對MASViewConstraint類中的內(nèi)容進行解析翁授。
1.MASViewConstraint的對象鏈?zhǔn)秸{(diào)用探索
MASViewConstraint的對象是支持鏈?zhǔn)秸{(diào)用的拣播,比如constraint.top.left.equalTo(superView).offset(10); 上面的這種方式就是鏈?zhǔn)秸{(diào)用,而且像equalTo(superView)這種形式也不是Objective-C中函數(shù)調(diào)用的方式收擦,在Objective-C中是通過[]來調(diào)用函數(shù)的贮配,而此處使用了()。接下來講分析這種鏈?zhǔn)降恼{(diào)用是如何實現(xiàn)的塞赂。
在MASViewConstraint類中的left, top等約束的getter方法都會調(diào)用下方的這個方法泪勒,而這個方法中所做的事情就是通過代理來調(diào)用工廠中的工廠方法來根據(jù)LayoutAttribute創(chuàng)建相應(yīng)的MASConstraint對象。
而像offset(10)這種調(diào)用方式是如何實現(xiàn)的呢宴猾?我們知道在OC中是不能通過小括號來調(diào)用方法的圆存,那邊閉包是可以的,不過offset()不是一個簡單的閉包仇哆。在offset()的代碼分析后我們不難發(fā)現(xiàn)offset() = offset + (); offset的代碼實現(xiàn)方式如下沦辙。offset是一個getter方法的名,offset函數(shù)的返回值是一個匿名Block, 也就是offset后邊的()讹剔。這個匿名閉包有一個CGFloat的參數(shù)油讯,為了支持鏈?zhǔn)秸{(diào)用該匿名閉包返回一個MASConstraint的對象。
2.install方法解析
MASViewConstraint中install方法負責(zé)創(chuàng)建MASLayoutConstraint對象延欠,并且將該對象添加到相應(yīng)的View上陌兑。下方代碼就是install中根據(jù)MASViewConstraint所收集的參數(shù)來創(chuàng)建NSLayoutConstraint對象,下方的MASLayoutConstraint其實就是NSLayoutConstraint的別名由捎。下方就是調(diào)用系統(tǒng)的NSLayoutConstraint為創(chuàng)建相應(yīng)的約束對象兔综,下方的構(gòu)造器與第一部分中的NSLayoutConstraint一致。
創(chuàng)建完約束對象后隅俘,我們要尋找該約束添加到那個View上邻奠。下方的代碼段就是獲取接收該約束對象的視圖。如果是兩個視圖相對約束为居,就獲取兩種的公共父視圖碌宴。如果添加的是Width或者Height,那么久添加到當(dāng)前視圖上蒙畴。如果既沒有指定相對視圖贰镣,也不是Size類型的約束,那么就將該約束對象添加到當(dāng)前視圖的父視圖上膳凝。代碼實現(xiàn)如下:
創(chuàng)建完約束對象碑隆,并且找到承載約束的視圖后,接下來就是將該約束添加到該視圖上蹬音。子啊添加約束是我們要判斷是不是對約束的更新上煤,如果是對約束的更新的話就先獲取已經(jīng)存在的約束并對該約束進行更新,如果被更新的約束不存在就進行添加著淆。添加成功后我們將通過mas_installedConstraints屬性記錄一下本安裝的約束劫狠。mas_installedConstraints是通過運行時為UIView關(guān)聯(lián)的一個NSMutable類型的屬性拴疤,用來記錄約束該視圖的所有約束。
3.UIView的私有類目UIView+MASConstraints
在MASViewConstraint中定義了一個UIView的私有類目UIView+MASConstraints独泞,該類目的功能為UIView通過運行時來關(guān)聯(lián)一個NSMutableSet類型的mas_installedConstraints屬性呐矾。該屬性中記錄了約束該View的所有約束。代碼實現(xiàn)如下懦砂。
因為篇幅有限檐春,今天的博客就先到這兒覆获。對Masonry框架中的代碼不可能在本篇博客中都進行一一介紹帆赢。不過在github上分享了一個Masonry的一個使用Demo以及源碼解析的工程下硕。其中對Masonry的關(guān)鍵代碼都進行了說明與注釋。下方是其github分享鏈接羽资。
github分享地址:https://github.com/lizelu/MasonryDemo