1、前言
首先,我認(rèn)為學(xué)習(xí)總結(jié),要有所總,所結(jié),就是有歸納后,能用自己的話告訴別人!有所結(jié),就是有所收獲輸出,一般我認(rèn)為是思維導(dǎo)圖,所以,每篇文章前,我都會先給出文章的腦圖:

2、正文
注意,本系列總結(jié)不會引用或提供原課程文章所有的內(nèi)容或代碼,只會作出思維導(dǎo)圖,需要學(xué)習(xí)可購買課程 《iOS開發(fā)高手課 - 極客時間》
帶問題找答案
- Auto Layout 如何實現(xiàn)自動布局的?
- 這種布局算法真的會影響性能嗎?
- 應(yīng)該選擇手動布局還是選擇Auto Layout呢?
文中提了3個問題,那么這3個問題怎么解答呢?可以利用第一篇文章說的,一個知識點的方法論來解答。這里就不展開了,具體可以查看 如何建立你自己的開發(fā)知識體系 | iHTCboy's blog
Auto Layout
- 為什么需要 Auto Layout
- 什么是 Auto Layout
- 怎么使用 Auto Layout
- 使用 Auto Layout 時注意的問題
- Auto Layout 的應(yīng)用領(lǐng)域
- Auto Layout 的優(yōu)缺點
- Auto Layout 觸類旁通
1. 為什么需要 Auto Layout
為什么需要?一般遇到解答不了的問題,可以試試逆向!,那就反推,就是 沒有 Auto Layout 之前是怎么樣的 ?沒有 Auto Layout 時,我們是通過設(shè)置元素的 Frame 來手動指定界面布局的大小和位置。
剛開始,大家的App并不復(fù)雜,頁面布局也很簡單,并且有一個歷史原因,就是 iPhone4/s(960x640像素)時代 (更早的 iPhone 3G/S,3G網(wǎng)絡(luò),S是速度 Speed,因為08、09年那會,一般國內(nèi)開發(fā)者估計都沒有見過,所以這里就簡單提一下。) ,iPhone 的寬度都是 640 像素, 開發(fā)時用 320 個點計算, 直到 2012年9月發(fā)布 iPhone5 (1136x640像素),屏幕高度增長了!4寸,當(dāng)時三星都開始5寸大屏了,大家當(dāng)年吐槽iPhone長的圖片大家可以搜索看看!此時此刻,適配 iPhone5 依然并沒有太大難度,蘋果默認(rèn)針對沒有適配 iPhone5 的App,在 iPhone5 打開App時,上下2端黑屏,這樣來過度。
就在當(dāng)年,2012年的 WWDC2012 蘋果發(fā)布了 Auto Layout 技術(shù),從 iOS6 以后開始支持(Xcode4)。2013年9月發(fā)布 iPhone5s,但是大多數(shù)的開發(fā)者還是習(xí)慣使用傳統(tǒng)的UI布局方式,大家的開發(fā)App布局并不會覺得麻煩,直到2014年才發(fā)生變化!
2014年9月,蘋果發(fā)布了 iPhoe 6(1334x750像素)、iPhone 6 plus(1920x1080像素),屏幕適配工作變得非常必要!如果用計算數(shù)值的方法工作量增加了幾倍。因為4個尺寸的屏幕不一樣!iPhone4/s(960x640像素)、iPhone 5/s (1136x640像素)、iPhoe 6(1334x750像素)、iPhone 6 plus(1920x1080像素),雖然大家還是可以按比例計算做縮放,但是這樣并不能解決所有問題,因為如果想像素級還原設(shè)計、效果圖調(diào)整尺寸等,可能都需要重新手動計算一次。所以,這樣算過程,應(yīng)該是2014年后才是 Auto Layout技術(shù)被大家廣泛應(yīng)用。我在 GitHub 查看了 iOS 最經(jīng)典的 Masonry 庫是 2013年7月22號 創(chuàng)建的,也是符合這個技術(shù)歷史的進(jìn)程啊~ (ps: Masonry 源碼值得研究學(xué)習(xí),有很多可學(xué)習(xí)的知識,詳細(xì)搜索引擎一下,已經(jīng)有很多好的文章啦~)
那么到此,大家明白了,為什么需要 Auto Layout 了嗎?
2. 什么是 Auto Layout
Auto Layout 是一種基于約束的、描述性的布局系統(tǒng)。也就是使用約束條件來描述布局,View 的 Frame 會根據(jù)這些描述來進(jìn)行計算。
3. 怎么使用 Auto Layout
2012年,Xcode4,iOS6 引入了 NSLayoutConstraint 類,并且 VFL (Visual Format Language,視覺格式語言) 的方式創(chuàng)建約束。通過下面2個方式來生成布局約束組:
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
關(guān)于具體使用和 VFL 相關(guān)使用可以查看官方文檔:Auto Layout Guide: Visual Format Language,所有學(xué)習(xí)資料官方文檔是第一手!
4. 使用 Auto Layout 時注意的問題
Constraint Churn(約束流失)
- Avoid removing all constraints (避免刪除所有約束)
- Add static constraints once (僅一次添加靜態(tài)約束,且不要再改變它們)
- Only change the constraints that need changing(只更改需要更改的約束)
- Hide views instead of removing them(隱藏視圖而不是刪除它們)
注:來自:High Performance Auto Layout - WWDC 2018 - Videos - Apple Developer
Summary
- Stack Views help build easily maintainable layouts (堆棧視圖有助于構(gòu)建易于維護(hù)的布局)
- Use activate and deactivate for constraints (使用激活和停用來約束)
- Determine size through constraints (通過約束確定尺寸)
- Override intrinsicContentSize judiciously (明智地覆蓋內(nèi)在內(nèi)容大小)
- Use priorities to properly solve your layout (使用優(yōu)先級來正確解決您的布局)
- Alignment goes beyond top, bottom, and center (對齊超出頂部,底部和中心)
- Keep localization in mind (記住本地化)
注:來自:Mysteries of Auto Layout, Part 1 - WWDC 2015 - Videos - Apple Developer
以上注意事項來自 WWDC,具體視頻可參考文章末尾的引用來源。這里不打算詳細(xì)解說,因為視頻真的說的很好,推薦大家去看看啊。
5. Auto Layout 的應(yīng)用領(lǐng)域
Auto Layout 其實,除了可以用代碼來創(chuàng)建,蘋果的可視化布局,也有使用,nib,xib,storyboard,那么大家對這3個東西了解熟悉嗎?
Interface Builder 工具
Interface Builder 在 Xcode 4 之前,是一個獨立的軟件,Xcode 4 開始集成到Xcode 中的。這個大家現(xiàn)在比較熟悉,就是可以用鼠標(biāo)以圖形化的方式,拖拉元素來創(chuàng)建UI界面。
NIB、XIB 區(qū)別
Xcode 3 前,Interface Builder 創(chuàng)建的文件是 NIB(二進(jìn)制格式,NeXT Interface Builder),不利于版本控制。
Xcode 3 開始,Interface Builder 使用了一種新的文件格式 XIB(XML文本格式,OS X Interface Builder或XML Interface Builder),XIB在工程編譯時被轉(zhuǎn)換成NIB;
XIB 文件
XIB 是一個描述文件,包含了用戶界面及相關(guān)元素;一個 XIB 文件對應(yīng)一個ViewController,也可以通過使用XIB來自定義View。
StoryBoard 故事板
iOS 5 (Xcode3)開始,Apple提供了一種全新的布局界面方式 StoryBoard 來拖拉創(chuàng)建界面;StoryBoard 是一組 ViewController 對應(yīng)的 XIB,以及它們之間的轉(zhuǎn)換方式的集合;在StoryBoard 中,不僅可以看到每個 ViewController 的布局樣式,也可以知道各個ViewController 之間的轉(zhuǎn)換關(guān)系。
對于2013~2015年,當(dāng)然非常的缺乏 iOS 開發(fā)者,所以一般的公司只有一個 iOS 開發(fā),那么這時候,StoryBoard 就是最快速的創(chuàng)建界面的工具!此時,面對多種設(shè)備時,Auto Layout 就是錦上添花,可以大幅提高 UI 開發(fā)效率,一次性做出適合所有屏幕尺寸的 UI。
現(xiàn)在,對使用 StoryBoard + Auto Layout 還是使用 代碼 + Masonry/SnapKit,依然沒有最終的答案,因為各有優(yōu)缺點。
6. Auto Layout 的優(yōu)缺點
Auto Layout的優(yōu)點不用多說,解決手動計算每個屏幕尺寸的布局,提高工程效率!缺點的話,大概就是適當(dāng)?shù)膶?dǎo)致性能降低?
Auto Layout 導(dǎo)致性能降低?是嗎?為什么是?為什么不是?前面的“什么是 Auto Layout”只是簡單的簡介,Auto Layout 是一個 布局系統(tǒng),沒有深入的介紹,不知道大家有沒有讀到那里時,產(chǎn)生疑問或興趣呢?
所以,要知道 Auto Layout 的優(yōu)缺點,還需要深入了解它的原理,才能理解優(yōu)缺點!否則,死記硬背過后還是不明不白。Auto Layout 是一套 布局引擎系統(tǒng),叫作 Layout Engine ,是 Auto Layout 的核心。了解 Layout Engine 的布局原理,是理解它的性能(優(yōu)缺點)的基礎(chǔ)。
所以在這里補(bǔ)充一下,主要參考蘋果官方的 WWDC 視頻來解說 Layout Engine,引用主講者 Jason Yao 說的:我們并不只想說這樣不好,我們相信大家真正的理解它,理解這個過程!剝開表面!了解真正發(fā)生了什么?:
The Render Loop (渲染循環(huán))

布局引擎是工作流程如上圖所示,Update Constraints(更新約束)流,從父視圖的約束開始更新,傳遞到子視圖,再到子子視圖,這里有2點要說明,一是這個更新約束只是從有約束變化的視圖開始,并不是所有視圖都更新;二是這個傳遞過程為什么是從父級開始,因為當(dāng)一個約束變化時,這個約束是自己與父級的關(guān)系或自己與子級的關(guān)系,所以會通知給子級視圖來響應(yīng)!Layout(布局)流,是從子視圖開始布局,為什么是反向呢?一個視圖的布局,它一定是由自己和所有的子視圖組成,那自己的布局一定是受子視圖的布局和約束影響,所以先確認(rèn)所有子視圖的約束,那自己的視圖就確實了,這個可能有點繞,大家可以看看原視頻來理解。Display (渲染顯示)流,因為子視圖布局確定了,那顯示的大小和位置就能確定,所以也是從子視圖開始顯示。
What is updateConstraints?(什么是 updateConstraints ?)

updateConstraints() 是視圖的約束更新時會調(diào)用的方法,可以重寫這個方法來自行設(shè)置約束條件。圖中列出了 Update Constraints(更新約束)、Layout(布局)、Display (渲染顯示) 的對應(yīng)關(guān)系的方法。這里與第一個圖并不是對應(yīng)的關(guān)系!而是這3個狀態(tài)的生命周期分別有對應(yīng)的方法來響應(yīng),要怎么理解?
要理解這個圖,最簡單是從了解 layoutSubviews()、setNeedsLayout()、layoutIfNeeded() 三者的關(guān)聯(lián)和作用,明白這3個方法的作用,那么就知道這個生命周期是什么意思。
setNeedsLayout():當(dāng)一個UIView對象此方法時,實際上等同于做了一個標(biāo)記,告訴系統(tǒng)需要重新布局,但不會立刻執(zhí)行,直到 drawing cycle 循環(huán)到達(dá)該節(jié)點時,才會調(diào)用layoutSubviews() 方法重新布局。
layoutIfNeeded():允許在 drawing cycle 循環(huán)到達(dá)該節(jié)點之前,就立刻執(zhí)行布局刷新調(diào)用 layoutSubviews() 方法。
layoutSubviews():在上面2個方法調(diào)用后,都會被調(diào)用。另外,當(dāng) addSubview、size 改變或滑動UIScrollView、旋轉(zhuǎn)Screen等都會觸發(fā)。
回到 updateConstraints()、setNeedsUpdateConstraints()、updateConstraintsIfNeeded(),那它們的作用也是對應(yīng)的關(guān)系?,F(xiàn)在剩下的問題就是,為什么需要這些方法???我們在開發(fā)中,是不是會改變視圖后,更馬上刷新這個頁面就會用到這些方法。那么同時,我們改變(更新)約束后,是不是也希望刷新約束?所以,這些方法的作用就是這樣,那么為什么要這樣做,有什么好處呢?因為約束更新,需要重新計算一次,那我們可以自己來控制要不要更新,能減少Constraint Churn(約束流失),減少性能損耗。為什么?舉例為說,你給一個Lable設(shè)置了新的字體,此時要不要馬上更新約束?如果你下一句代碼是設(shè)置新的字體大小呢?所以,你可以控制一組約束,什么時候才更新,現(xiàn)在明白了這些方法和它們對應(yīng)的關(guān)系了吧。剩下的 draw(_:) 和 setNeedsDisplay() 也是同理,只是層級更底,渲染的調(diào)用刷新。
Activating a Constraint(激活一個約束)

說了這么多,好像還沒有說到 Layout Engine 布局引擎的工作流程。這個圖就是這個流程,每個 Window 下有一個 Engine(引擎),那么 View(視圖) 包含 Variable(變量)和 Constraint(約束),那么 Engine 與 View 之間通過 Equation(等式) 聯(lián)系。
那么要理解布局引擎的工作,其實很簡單,就是Constraint約束描述了View視圖的位置和大?。╯ize),那么就通過 Variable(變量)來向引擎獲取,需要獲取什么?
minY minX height width,那現(xiàn)在引擎需要做的就是把約束解析出這4個值,所以就是通過 Equation(等式)求解。Equation等式其實也很容易理解,就是像下面這些:
text1.minX = 8
text1.width = 100
text2.minX = text1.minX + text1.width +20
最后解出等式,等到結(jié)果:
text1.minX = 8
text1.width = 100
text2.minX = 128
所以,布局引擎的核心就是這個等式的計算,我們初中就算了一元二次方程式,后來學(xué)習(xí)了多次方程式求解,是不是覺得很簡單?那么這些數(shù)學(xué)問題,我們讀書時就知道數(shù)字題目答案只有一個,但是解法有很多!,所以原文章提到 Cassowary 算法、Simplex 算法 就是解決這個方程式求解的問題。我們?nèi)丝梢宰鲆恍}操作,但是要程序操作,一定是通用的解法,這也是算法為什么難!數(shù)學(xué)為什難!因為找到規(guī)律的人,往往是牛逼的人!
Equation(等式)求解的結(jié)果,通過 setNeedsLayout() 通知所有的視圖,視圖通過 UIView.layoutSubviews() 方法從引擎中復(fù)制數(shù)據(jù)到子視圖(Copying data from engine to subview)。
所以,這個就是整個引擎工作的過程!不知道我說的明白不明白!理解了這個過程,就能回復(fù)前面的 Auto Layout 會導(dǎo)致性能降低?從原理上說,引擎的工作方式和我們開發(fā)者手動計算的過程是一樣的!導(dǎo)致性能降低的原因,是因為一些約束流失(Constraint Churn)、不可滿足約束(Unsatisfiable Constraints)等導(dǎo)致消耗大量計算??赡苣銜幸蓡枺簽槭裁匆娌粫錾凳履兀勘热缥易约河嬎愕牟季?,我都緩存了,引擎做了嗎?答案是肯定的,Engine is a layout cache and tracker(引擎是一個布局緩存和約束跟蹤器),也就是你設(shè)置的布局,如果不必更新是不會更新約束的;同時,約束更新時引擎會知道那些約束需要重新計算,那么不需要再計算!所以,引擎系統(tǒng)導(dǎo)致性能降低本質(zhì)來說可以忽視,剩下的就是,如何避免我們設(shè)置約束時不合理導(dǎo)致性能降低呢?可以參考前面一節(jié):“4. 使用 Auto Layout 時注意的問題”,詳細(xì)的所有原則這里就不展開了,下面會重點提幾個。到此,引擎的原理問題算是解決啦!
Building a More Performant Layout(構(gòu)建一個更好的性能布局)

這些列舉了我們常見的 TableView 滾動卡頓的問題,其實我們知道原因,就是滾動過程中 Cell 要重繪,需要我們知道 Cell 可以重用,但是每個 Cell 的布局和長度可能千變?nèi)f化,所以卡頓的問題,有一個就是 Cell 變化過程中,重新布局的問題。首先,避免刪除所有約束,因為所有約束重新計算可能不是必要的,比如上圖的用戶頭像的位置和大小,固定約束后就不要去改變它啦!那么,可能有一些 Cell 有圖片,有一些 Cell 沒有時,可以通過 setHidden: 方法 和 noImageConstraints 圖片的單獨約束來控制,這樣,盡最大可以減少約束的計算,導(dǎo)致性能的降低,從而盡可能的避免卡頓!另外,使用 Auto Layout 可以多使用 Compression Resistance Priority 和 Hugging Priority,利用優(yōu)先級的設(shè)置,讓布局更加靈活,代碼更少,更易于維護(hù)。
以上內(nèi)容來源: High Performance Auto Layout - WWDC 2018 - Videos - Apple Developer
Independent Sibling Views(獨立的兄弟視圖)

前面說到 如何避免我們設(shè)置約束時不合理導(dǎo)致性能降低呢?我們已經(jīng)知道引擎需要計算方程式求解,對于每個元素視圖單獨約束,相互不依賴時,其實就是解決一元一次方程式,所以就是一條直線。對于我們開發(fā)來說,避免約束的相互依賴就能減少性能消耗,所以我們設(shè)置約束時,能不依賴的約束的視圖,讓他們保持獨立!就是最優(yōu)解!
Dependent Sibling Views(互相依賴的兄弟視圖)

對于相互依賴的約束,它們就構(gòu)形了多元方程式,依賴關(guān)系越多,曲線就越陡峭。所以,我們能做的還是一樣,盡量減少多個視圖之前的約束依賴!
Nested Views(嵌套的視圖)

對于嵌套的視圖,同理,減少視圖的嵌套,減少嵌套的層級,都是解決性能的重要手段!
以上內(nèi)容來源:What's New in Cocoa Touch - WWDC 2018 - Videos - Apple Developer 。更多的技巧,可以參考前面一節(jié):“4. 使用 Auto Layout 時注意的問題”。
Building the Layout(構(gòu)建布局)

前面只是簡單的說明了引擎就是計算出視圖的位置和大小,那么具體是怎么計算的呢?這個圖片顯示了布局引擎的工作流。每個視圖在得到自己的布局之前,Layout Engine 會將視圖、約束、優(yōu)先級、固定大小等通過計算轉(zhuǎn)換成最終的位置和大小。

所以,最終的 Layout Engine 計算到布局就是這樣的過程,細(xì)節(jié)點還有很多。還是那句話,授人以魚不如授人以漁!大家有“漁”后,自然要自己捉魚!,這里就不詳細(xì)解進(jìn)了,可觀看 WWDC 視頻:Mysteries of Auto Layout, Part 1 - WWDC 2015 - Videos - Apple Developer。
最后,關(guān)于 Auto Layout 還有很多知識,比如怎么調(diào)試 Auto Layout 的 Debug?可以查看 What's New in Auto Layout - WWDC 2016 - Videos - Apple Developer 視頻。Auto Layout 的流程(The Layout Cycle),可以查看 Mysteries of Auto Layout, Part 2 - WWDC 2015 - Videos - Apple Developer。
7. Auto Layout 觸類旁通
UIStackView 與 Flexbox
UIStackView 是2015年 iOS9 蘋果推出的一套 API,它可以很好地減輕手動寫或拖 constraint 帶來的重復(fù)繁瑣的工作,也可以自動化的處理排列和元素個數(shù)的變化。(當(dāng)年因為需要iOS9+,導(dǎo)致很少有開發(fā)者使用,放在2020年的今年,這個控件可以熟悉一下?。。┡c Web 前端的 Flexbox 響應(yīng)式布局是一個原理。UIStackView 特點有下面4個:
- Easy to build(容易構(gòu)建)
- Easy to maintain (容易維護(hù))
- Composable Stack Views (可組合的堆棧視圖)
- Lightweight (輕量級)
這里并不打算講解 UIStackView 有多利害!確實它很利害。具體可以查看 WWDC 演示的Demo Mysteries of Auto Layout, Part 1 - WWDC 2015 - Videos - Apple Developer。
關(guān)于 Flexbox 的思想可以看看文章 30 分鐘學(xué)會 Flex 布局 - 知乎 和 Flex 布局教程:語法篇 - 阮一峰的網(wǎng)絡(luò)日志,個人覺得文章寫得很好。另外關(guān)于 UIStackView 的強(qiáng)大就借 UIStackView 入坑指南 - 掘金 文章的一張圖來總結(jié)吧:

SwiftUI
-
命令式編程(Imperative Programming):命令“機(jī)器”如何去做事情(how),這樣不管你想要的是什么(what),它都會按照你的命令實現(xiàn)。 -
聲明式編程(Declarative Programming):告訴“機(jī)器”你想要的是什么(what),讓機(jī)器想出如何去做(how)。
SwiftUI 是聲明式編程,還有函數(shù)式編程、響應(yīng)式編程 等編程思想,這里就不說了。這里提的原因是,SwiftUI 采用不同的布局方式,但是依然使用 Auto Layout,并且 VStack 也是天合之作吧!
3、總結(jié)
首先,關(guān)于 iOS 、 Xcode 和對應(yīng)年份的關(guān)系,可以梳理一下,2012年 Xcode4 對應(yīng) iOS 6 ,2013年 Xcode5 和 iOS 7。它們相差2,所以,2020年將發(fā)布 Xcode12 和 iOS 14。這個就是一個數(shù)字游戲,可記可不記,就是想說明,記憶可以找規(guī)律的。
回到最前面提到的3個疑問題,你是不是已經(jīng)有了自己的答案了呢?
- Auto Layout 如何實現(xiàn)自動布局的?
- 這種布局算法真的會影響性能嗎?
- 應(yīng)該選擇手動布局還是選擇Auto Layout呢?
本章內(nèi)容夠不夠深不深入?這個大家的了解水平不一樣,如果覺得不夠深入,還是可以參考本文末的參考擴(kuò)展了解更多,因為 WWDC 視頻中提到了很多細(xì)節(jié)的東西,有一些很棒,有一些很有趣,這里就不一一列出。因為原文還提到了 Cassowary 算法、Simplex 算法,本文并沒有把它作為主角色來解讀,為什么呢?因為,它并不是我們了解和理解 Auto Layout 最核心的必備知識,并且它對技術(shù)有要求,不可能每個人都能看懂,否則文章一上來就會讓讀者害怕,適得其反。所以,在本文的基礎(chǔ)上,如果大家還想深入了解,那這將是一道窗口,而不是一道門口!
以后關(guān)于 Auto Layout 的知識,你是不是能更好的跟別人講解呢?這些就是本文想要做的事情,當(dāng)然還有更深入的知識可以研究,切記這只是開始!修行在個人~
注:更多關(guān)于 iOS 開發(fā)和程序開發(fā)相關(guān)的內(nèi)容,可以查看系列,目前還在連載中 【學(xué)習(xí)總結(jié)】iOS開發(fā)高手課 -- (連載中) | iHTCboy's blog,以上,希望對你有用!
參考
WWDC:
- High Performance Auto Layout - WWDC 2018 - Videos - Apple Developer
- Mysteries of Auto Layout, Part 1 - WWDC 2015 - Videos - Apple Developer
- Mysteries of Auto Layout, Part 2 - WWDC 2015 - Videos - Apple Developer
- What's New in Auto Layout - WWDC 2016 - Videos - Apple Developer
- What's New in Cocoa Touch - WWDC 2018 - Videos - Apple Developer
- Auto Layout Techniques in Interface Builder - WWDC 2017 - Videos - Apple Developer
- Implementing UI Designs in Interface Builder - WWDC 2015 - Videos - Apple Developer
- What's New in Storyboards - WWDC 2015 - Videos - Apple Developer
- Best Practices for Mastering Auto Layout - WWDC 2012 - Videos - Apple Developer
Article:
- Auto Layout Guide: Understanding Auto Layout
- Solving Linear Arithmetic Constraints for User Interface Applications - PDF
- Solving Linear Arithmetic Constraints for User Interface Applications
- UW Cassowary Constraint Solving Toolkit
- Simplex algorithm - Wikipedia
- CSS - flexbox
- Flex 布局教程:語法篇 - 阮一峰的網(wǎng)絡(luò)日志
- 30 分鐘學(xué)會 Flex 布局 - 知乎
- UIStackView 入坑指南 - 掘金
- UIStackView學(xué)習(xí)分享, 純代碼實現(xiàn) - 簡書
- johnlui/AutoLayout: Auto Layout 秘境
- iOS學(xué)習(xí)筆記02——以編碼的方式實現(xiàn)Auto Layout自動布局(一)AutoLayout,iOS,自動布局董寶君的博客-CSDN博客
- iOS學(xué)習(xí)筆記04——Visual Format Language語法的簡單學(xué)習(xí)_董寶君的博客-CSDN博客
- cocoa - What is the difference between NIB and XIB Interface Builder file formats? - Stack Overflow
- xib與nib的區(qū)別_雅香小筑-CSDN博客
- NIB、XIB、StoryBoard與UIViewController、UIView - TIME TO GO
- 響應(yīng)式和函數(shù)式,兩個容易混淆的概念 - 簡書
- 從 Auto Layout 的布局算法談性能
- 深入理解 Autolayout 與列表性能 -- 背鍋的 Cassowary 和偷懶的 CPU - 掘金
- Auto Layout Guide: Visual Format Language
- Simplex algorithm - Wikipedia
- Masonry · ming1016/study Wiki
- forkingdog/FDStackView: Use UIStackView directly in iOS6+
- ming1016/STMAssembleView: 制作一個類似蘋果VFL(Visual Format Language)的格式化語言來描述類似UIStackView那種布局思路,并解析生成頁面
- 深入剖析Auto Layout,分析iOS各版本新增特性 | 星光社 - 戴銘的博客
- iOS關(guān)于setNeedsLayout、layoutIfNeeded、 layoutSubviews、drawRect的愛恨情仇 - 簡書
- 聲明式編程和命令式編程的比較知識庫博客園
- 如有侵權(quán),聯(lián)系必刪!
- 如有不正確的地方,歡迎指導(dǎo)!
- 如有疑問,歡迎在評論區(qū)一起討論!
注:本文首發(fā)于 iHTCboy's blog,如若轉(zhuǎn)載,請注來源