Auto Layout 自動布局

原文鏈接
Auto Layout 伪嫁,是蘋果公司提供的一個基于約束布局薄辅,動態(tài)計算視圖大小和位置的庫,并且已經(jīng)集成到了 Xcode 開發(fā)環(huán)境里。

在引入 Auto Layout 這種自動布局方式之前,iOS 開發(fā)都是采用手動布局的方式。
而手動布局的方式璃诀,原始落后、界面開發(fā)維護(hù)效率低蔑匣,對從事過前端開發(fā)的人來說更是難以適應(yīng)劣欢。
所以,蘋果需要提供更好的界面引擎來提升開發(fā)者的體驗裁良,Auto Layout 隨之出現(xiàn)凿将。

蘋果公司早在 iOS 6 系統(tǒng)時就引入了 Auto Layout,但是直到現(xiàn)在還有很多開發(fā)者遲遲不愿使用 它趴久,其原因就在于對其性能的擔(dān)憂丸相。
即使后來,蘋果公司推出了在 Auto Layout 基礎(chǔ)上模仿前端 Flexbox 布局思路的 UIStackView 工具彼棍,提高了開發(fā)體驗和效率,也無法解除開發(fā)者們對其性能的顧慮膳算。

Auto Layout 到底是如何實現(xiàn)自動布局的座硕,這種布局算法真的會影響性能嗎?

Auto Layout 的來歷
  • 1997 年涕蜂,Auto Layout 用到的布局算法 Cassowary 被發(fā)明了出來华匾;
  • 2011 年,蘋果公司將 Cassowary 算法運用到了自家的布局引擎 Auto Layout 中。

Cassowary 能夠有效解析線性等式系統(tǒng)和線性不等式系統(tǒng)蜘拉,用來表示用戶界面中那些相等關(guān)系和不等關(guān)系萨西。基于此旭旭,Cassowary 開發(fā)了一種規(guī)則系統(tǒng)谎脯,通過約束來描述視圖間的關(guān)系。
約束就是規(guī)則持寄,這個規(guī)則能夠表示出一個視圖相對于另一個視圖的位置源梭。

由于 Cassowary 算法讓視圖位置可以按照一種簡單的布局思路來寫,這些簡單的相對位置描述可以在運行時動態(tài)地計算出視圖具體的位置稍味。視圖位置的寫法簡化了废麻,界面相關(guān)代碼也就更易于維護(hù)。蘋果公司也是看重了這一點模庐,將其引入到了自己的系統(tǒng)中烛愧。

由于 Cassowary 算法本身的先進(jìn)性,更多的開發(fā)者將 Cassowary 運用到了各個開發(fā)語言中掂碱,比如 JavaScript怜姿、.NET、Java顶吮、Smalltalk社牲、C++ 都有對應(yīng)的庫。

Auto Layout 的生命周期

Auto Layout 不只有布局算法 Cassowary悴了,還包含了布局在運行時的生命周期等一整套布局引擎系統(tǒng)搏恤,用來統(tǒng)一管理布局的創(chuàng)建、更新和銷毀湃交。了解 Auto Layout 的生命周期熟空,是理解它的性能相關(guān)話題的基礎(chǔ)。這樣搞莺,在遇到問題息罗,特別是性能問題時,我們才能從根兒上找到原因才沧,從而避免或改進(jìn)類似的問題迈喉。

這一整套布局引擎系統(tǒng)叫作 Layout Engine ,是 Auto Layout 的核心温圆,主導(dǎo)著整個界面布局挨摸。

每個視圖在得到自己的布局之前,Layout Engine 會將視圖岁歉、約束得运、優(yōu)先級、固定大小通過計算轉(zhuǎn)換成最終的大小和位置。在 Layout Engine 里熔掺,每當(dāng)約束發(fā)生變化饱搏,就會觸發(fā) Deffered Layout Pass , 完成后進(jìn)入監(jiān)聽約束變化的狀態(tài)置逻。當(dāng)再次監(jiān)聽到約束變化推沸,即進(jìn)入下一輪循環(huán)中。整個過程如下圖所示:

圖中诽偷,Constraints Change 表示的就是約束變化坤学,添加、刪除視圖時會觸發(fā)約束變化报慕。
Activating 或 Deactivating深浮,設(shè)置 Constant 或 Priority 時也會觸發(fā)約束變化。

Layout Engine 在碰到約束變化后會重新計算布局眠冈,獲取到布局后調(diào)用 superview.setNeedLayout()飞苇,然后進(jìn)入 Deferred Layout Pass。

Deferred Layout Pass 的主要作用是做容錯處理蜗顽。如果有些視圖在更新約束時沒有確定或缺失布局聲明的話布卡,會先在這里做容錯處理。

接下來雇盖,Layout Engine 會從上到下調(diào)用 layoutSubviews() 忿等,通過 Cassowary 算法計算各個子視圖的位置,算出來后將子視圖的 frame 從 Layout Engine 里拷貝出來崔挖。

在這之后的處理贸街,就和手寫布局的繪制、渲染過程一樣了狸相。所以薛匪,使用 Auto Layout 和手寫布局的區(qū)別,就是多了布局上的這個計算過程脓鹃。

Auto Layout 性能問題

iOS 12 之前逸尖,很多約束變化時都會重新創(chuàng)建一個計算引擎 NSISEnginer 將約束關(guān)系重新加進(jìn)來,然后重新計算瘸右。結(jié)果就是娇跟,涉及到的約束關(guān)系變多時,新的計算引擎需要重新計算太颤,最終導(dǎo)致計算量呈指數(shù)級增加逞频。

iOS12 之后的 Auto Layout 更多地利用了 Cassowary 算法的界面更新策略,使其真正完成了高效的界面線性策略計算栋齿。

使用 Auto Layout 一定要注意多使用 Compression Resistance Priority 和 Hugging Priority,利用優(yōu)先級的設(shè)置,讓布局更加靈活瓦堵,代碼更少基协,更易于維護(hù)。

那么菇用,明確了 iOS 12 使得 Auto Layout 具有了和手寫布局幾乎相同的高性能后澜驮,你是不是就可以放心地使用 Auto Layout 了呢?答案是肯定的惋鸥。

常見問題

  1. 幾個方法的區(qū)別
  • setNeedsLayout:告知頁面需要更新杂穷,但是不會立刻開始更新。
    執(zhí)行后會立刻調(diào)用layoutSubviews卦绣。

  • layoutIfNeeded:如果有需要刷新的標(biāo)記耐量,立即調(diào)用layoutSubviews進(jìn)行布局;
    如果沒有標(biāo)記滤港,不會調(diào)用layoutSubviews廊蜒。
    如果希望立刻生成新的frame需要調(diào)用此方法,
    利用這點一般布局動畫可以在更新布局后直接使用這個方法讓動畫生效溅漾。

  • layoutSubviews:對subviews進(jìn)行布局山叮,不能主動調(diào)用,需要的時候在子類重寫添履,系統(tǒng)會在合適的時候自動調(diào)用屁倔。
    注意 : 如果要立即刷新frame,要先調(diào)用setNeedsLayout()暮胧,把標(biāo)記設(shè)為需要布局锐借,然后馬上調(diào)用layoutIfNeeded(),實現(xiàn)布局叔壤。

  • setNeedsUpdateConstraints:告知需要更新約束瞎饲,但是不會立刻開始

  • updateConstraintsIfNeeded:告知立刻更新約束

  • updateConstraints:系統(tǒng)更新約束

  1. 系統(tǒng)調(diào)用layoutSubviews的時機
  • init初始化不會觸發(fā)layoutSubviews,但是使用initWithFrame進(jìn)行初始化且rect不為zero時炼绘,會調(diào)用layoutSubviews嗅战。
  • addSubview的時候會觸發(fā)系統(tǒng)調(diào)用layoutSubviews。
  • 當(dāng)view的frame發(fā)生改變的時候觸發(fā)layoutSubviews俺亮。
  • 滾動一個UIScrollView會觸發(fā)layoutSubviews驮捍。
  • 旋轉(zhuǎn)Screen會觸發(fā)父UIView上的layoutSubviews事件。
  • 改變一個UIView大小的時候也會調(diào)用父UIView上的layoutSubviews事件
  1. 什么時候使用frame布局脚曾,什么時候選用Auto Layout布局

簡而言之东且,簡單的 UI 使用 Auto Layout ,復(fù)雜的 UI 使用 frame本讥。

原因如下:
從代碼量上來看珊泳,兩種布局方式相差不大鲁冯。有時候發(fā)現(xiàn)復(fù)雜的 UI 使用 Auto Layout 的話,代碼量反而會變多色查,因為復(fù)雜的 UI 往往會有復(fù)雜的邏輯薯演,比如根據(jù)數(shù)據(jù)的不同,部分 UI 的顯示會有變動(比如某個子視圖隱藏與顯示秧了, 會影響到其它視圖的布局)跨扮。
固定的UI簡單的布局,這種情況下使用 Auto Layout 還是挺方便的验毡,具有快速衡创、方便、簡潔的布局效果晶通。
動態(tài)復(fù)雜的 UI 布局璃氢,這種情況下使用 Auto Layout 來布局,感覺就不合適录择。因為不管是 frame 還是 Auto Layout拔莱,都需要去計算高度,Auto Layout通過 Cassowary 算法計算各個子視圖的位置隘竭,算出來后將子視圖的 frame 從 Layout Engine 里拷貝出來塘秦;而frame布局,則可以快速的通過事先約定的布局計算出相應(yīng)的frame动看,再進(jìn)行相應(yīng)的繪制尊剔、渲染。這種情況下菱皆,直接使用 frame 會比較精簡须误。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仇轻,隨后出現(xiàn)的幾起案子京痢,更是在濱河造成了極大的恐慌,老刑警劉巖篷店,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祭椰,死亡現(xiàn)場離奇詭異,居然都是意外死亡疲陕,警方通過查閱死者的電腦和手機方淤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹄殃,“玉大人携茂,你說我怎么就攤上這事∽缪遥” “怎么了讳苦?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵带膜,是天一觀的道長。 經(jīng)常有香客問我医吊,道長钱慢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任卿堂,我火速辦了婚禮,結(jié)果婚禮上懒棉,老公的妹妹穿的比我還像新娘草描。我一直安慰自己,他們只是感情好策严,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布穗慕。 她就那樣靜靜地躺著,像睡著了一般妻导。 火紅的嫁衣襯著肌膚如雪逛绵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天倔韭,我揣著相機與錄音术浪,去河邊找鬼。 笑死寿酌,一個胖子當(dāng)著我的面吹牛胰苏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播醇疼,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼硕并,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了秧荆?” 一聲冷哼從身側(cè)響起倔毙,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乙濒,沒想到半個月后陕赃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡琉兜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年凯正,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豌蟋。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡廊散,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出梧疲,到底是詐尸還是另有隱情允睹,我是刑警寧澤运准,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站缭受,受9級特大地震影響胁澳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜米者,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一韭畸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蔓搞,春花似錦胰丁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蒲祈,卻和暖如春甘萧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背梆掸。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工扬卷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沥潭。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓邀泉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钝鸽。 傳聞我的和親對象是個殘疾皇子汇恤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

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