簡單好用的iOS自動布局框架

有感于iOS自動布局代碼的冗長和繁瑣,閑來無事,便自己封裝了一下。
寫的過程中我借鑒了NSLayoutAnchor和masonry的一些思路议薪,寫了充分的單元測試用例,并對框架的性能(耗時和內(nèi)存占用)做了一個簡單評估媳友。

優(yōu)點

  • 簡單斯议,17KB大小。易用庆锦,對于許多布局捅位,用起來跟frame差不多
  • 支持iOS8和swift
  • 速度是masonry的1.7倍轧葛,接近系統(tǒng)方法速度搂抒,占用內(nèi)存小
  • 跟蹤所有約束艇搀,不需要額外寫成員屬性引用約束
  • 充分的單元測試
  • 支持iOS11,相對safeAreaLayoutGuide的布局約束書寫非常簡便求晶!
和系統(tǒng)方法焰雕、Masonry在性能上的比較

設(shè)置約束

所有約束設(shè)置都遵循系統(tǒng)的公式:

firstItem.firstAttribute {=,<=,>=} secondItem.secondAttribute * multiplier + constant

簡便寫法(適用于NSLayoutRelationEqual、multiplier = 1 且除了寬芳杏、高以外的約束的constant = 0的情況)

[self.redView activateConstraints:^{
    self.redView.height_attr.constant = 100; // redView的高度 = 100
    self.redView.width_attr = self.blueView.width_attr; // redView的寬度 = blueView的寬度
    self.redView.top_attr = self.blueView.top_attr; // redView的頂部 = blueView的頂部
    self.redView.left_attr = self.blueView.right_attr; // redView的左邊 = blueView的右邊
}];

常規(guī)寫法

[self.redView activateConstraints:^{
    self.redView.height_attr.constant = 150; // redView的高度 = 150
    [self.redView.width_attr equalTo:self.blueView.width_attr constant:50]; // redView的寬度 = blueView的寬度 + 50
    [self.redView.top_attr equalTo:self.blueView.top_attr constant:-10]; // redView的頂部 = blueView的頂部 - 10
    [self.redView.left_attr greaterThan:self.blueView.right_attr constant:20]; // redView的左邊 >= blueView的右邊 + 20
}];

activateConstraints方法會將block里所有約束都綁定給調(diào)用者矩屁,這里就是self.redView,這么做是為了方便以后獲取約束爵赵。
也可以用更接近系統(tǒng)的風(fēng)格設(shè)置約束吝秕,但這樣以后想獲取特定的某個約束就比較麻煩,需要創(chuàng)建一個成員變量引用以后想改變的約束空幻。

NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:4];
[arrayM addObject:[self.redView.height_attr equalTo:nil constant:100]];
[arrayM addObject:[self.redView.width_attr equalTo:self.blueView.width_attr]];
[arrayM addObject:[self.redView.top_attr equalTo:self.blueView.top_attr]];
[arrayM addObject:[self.redView.left_attr equalTo:self.blueView.right_attr]];
[NSLayoutConstraint activateConstraints:arrayM];

更新safeAreaLayoutGuide布局寫法烁峭,不需要寫版本判斷

[self.redView activateConstraints:^{
    self.redView.height_attr.constant = 100; // redView的高度 = 100
    self.redView.width_attr = self.blueView.width_attr; // redView的寬度 = blueView的寬度
    self.redView.top_attr = self.view.top_attr_safe; // redView的頂部 = view的safeAreaLayoutGuide的頂部,非iOS11則是view的頂部
    self.redView.left_attr = self.view.right_attr_safe; // redView的左邊 = view的safeAreaLayoutGuide的右邊秕铛,非iOS11則是view的右邊
}];

改變約束值

self.blueView.width_attr.constant = 100;

或者

[self.redView constraintAccordingToAttribute:self.redView.height_attr].constant = 100;

獲取約束

獲取非常方便约郁,當(dāng)初創(chuàng)建約束是怎樣的相對關(guān)系,通過相同的關(guān)系就可以獲取約束但两。

NSLayoutConstraint *cons = [self.titleLabel constraintAccordingToAttribute:self.titleLabel.bottom_attr andAttribute:self.subtitleLabel.top_attr];

激活和關(guān)閉約束

[self.redView activateConstraintAccordingToAttribute:self.redView.height_attr];
[self.redView deactivateConstraintAccordingToAttribute:self.redView.height_attr];

注意:調(diào)用deactivateConstraintAccordingToAttribute會將該約束對象銷毀鬓梅,這里保持跟系統(tǒng)的deactivateConstraint方法一致。如果只是想暫時關(guān)閉約束谨湘,以后想再activate绽快,則應(yīng)該獲取約束后,設(shè)置.active = NO

解釋一下核心方法 -(void)activateConstraints:(void (^)())constraints悲关;
這是UIView的一個對象方法谎僻,一般來說每個UIView的布局代碼寫在自己的block里, 只有調(diào)一次該方法寓辱,才會給這個方法的調(diào)用者創(chuàng)建一個用來引用布局對象的可變數(shù)組艘绍,以后才可以通過這個調(diào)用者拿到里面的布局對象。
并且只要調(diào)用了一次該方法秫筏,以后即使不在該方法的block里寫的約束诱鞠,約束的firstItem如果和該方法的調(diào)用者是一個對象,也會把這個約束添加到firstItem(調(diào)用者)的數(shù)組里这敬。
如果調(diào)用了activateConstraints后航夺,又希望移除對應(yīng)view的數(shù)組,可以調(diào)用
- (void)deactivateAllConstraintsAndAssociatedObjects

具體使用請移步github下載示例代碼崔涂。


添加到項目

使用CocoaPods
在podfile中加入 'NSLayoutConstraint-SSLayout'
直接使用源代碼
將Source文件夾下的文件copy到項目

傳送門:https://github.com/suruihai/NSLayoutConstraint-SSLayout

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阳掐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缭保,老刑警劉巖汛闸,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異艺骂,居然都是意外死亡诸老,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門钳恕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來别伏,“玉大人,你說我怎么就攤上這事忧额±灏梗” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵睦番,是天一觀的道長轴脐。 經(jīng)常有香客問我,道長抡砂,這世上最難降的妖魔是什么大咱? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮注益,結(jié)果婚禮上碴巾,老公的妹妹穿的比我還像新娘。我一直安慰自己丑搔,他們只是感情好厦瓢,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著啤月,像睡著了一般煮仇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谎仲,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天浙垫,我揣著相機(jī)與錄音,去河邊找鬼郑诺。 笑死夹姥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辙诞。 我是一名探鬼主播辙售,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼飞涂!你這毒婦竟也來了旦部?” 一聲冷哼從身側(cè)響起祈搜,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎士八,沒想到半個月后夭问,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡曹铃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了捧杉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陕见。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖味抖,靈堂內(nèi)的尸體忽然破棺而出评甜,到底是詐尸還是另有隱情,我是刑警寧澤仔涩,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布忍坷,位于F島的核電站,受9級特大地震影響熔脂,放射性物質(zhì)發(fā)生泄漏佩研。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一霞揉、第九天 我趴在偏房一處隱蔽的房頂上張望旬薯。 院中可真熱鬧,春花似錦适秩、人聲如沸绊序。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骤公。三九已至,卻和暖如春扬跋,著一層夾襖步出監(jiān)牢的瞬間阶捆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工钦听, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留趁猴,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓彪见,卻偏偏與公主長得像儡司,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子余指,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

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