WWDC之Mysteries of Auto Layout Part 2

本文為WWDC2015的Session 219 "Mysteries of Auto Layout Part2" 視頻筆記,其內容主要涉及了約束的生命周期和,Autolayout調試兩大內容,學習記錄了視頻內容重要的知識內容,歡迎一起探討研究.

資源

內容

The Layout Cycle

layoutCycle.png

為了說明Layout Cycle,蘋果工程師給出了這樣以上這張圖,果然一圖勝千言.基于整個App的運行循環過程中,布局界面上的視圖前,首先會進行約束進行更新和設置,然后將最終的布局信息延時地傳遞給視圖,讓視圖獲取到相關Frame的信息,進行位置的尺寸的確定,然后回到主運行循環,等待約束再發生變化.

Constraints Change

  • 約束改變后Frame不會馬上變化
  • 重寫layoutSubviews要十分當心

讓約束發生變化的方式主要由以下三種:
1.使用官方極力推薦的NSLayoutConstraint的``activedeactive`兩個類方法來激活,或無效指定約束.(拋棄掉add/remove約束的方式吧~原因可見Mysteries of Auto Layout Part1 16:27)
方法代碼如下:

    [NSLayoutConstraint activateConstraints:]
    [NSLayoutConstraint deactivateConstraints:]
    // 參數為NSLayoutConstraint對象的數組

2.修改約束等式的常量值,乘數因子或者優先值.接觸過Autolayout我們應該都知道給視圖設置約束時要滿足一個約束等式如下.(就當你知道了,(╯﹏╰)b)

equal.png

Constant或者Multipler變化時,創建的約束等式也相應改變,使得
Layout引擎重寫計算布局.
而對于優先值Priority的改變,往往表現在兩個視圖間同一位置的約束,將根據優先級高的計算布局屬性,除此之外還有具有instrinsic Content Size屬性的視圖間的contentCompressionResistance或者contentHug的競爭.

3.添加或移除視圖,視圖都沒,跟自己相關的約束當然也沒有嘍.(╮(╯▽╰)╭)

當約束改變后,Layout引擎就會重新計算新的布局,將布局內容的舊值替換成新值,然后調用父視圖的setNeedsLayout.
而對于setNeedsLayout的描述,官方文檔給出了詳細說明.此方法只是對當前約束變化了的視圖了標記,只有等到下一個視圖更新周期時視圖才會真正響應約束的變化而改變Frame.如果想要讓視圖快速地響應約束的變化,則需要調用layoutIfNeeded.

Deferred Layout Pass

約束發生變化后,就進入了延遲的布局信息傳遞過程.為什么說延時的呢?回想一下,我們操作約束變化時經常通過設置動畫時間來放大對應Frame的延時改變.在這個階段里,視圖更新所在視圖層次內的所有約束,然后重新賦值Frame屬性.
更新視圖的約束,使用setNeedsUpdateConstraints 就表示著該視圖的約束需要更新,而具體的更新會在將來某一時刻進行.其調用的時機,蘋果工程師給了兩個情景:

  • 當某約束在所在位置變化太慢時,使用update期間將更快的更新約束.
  • 當視圖約束頻繁且多余的變化時,調用后只會執行最后一次的更新變化.

響應視圖布局約束變化后,就到了對視圖位置布局的最終設置,而這個過程則是視圖從上到下遍歷視圖層次,調用layoutSuviews(iOS)/layout(OSX),設置具體的內部子視圖的Frame.而重寫該方法時,主講人多次提醒開發者需要十分注意重寫方法時內部的操作.
重寫layoutSuviews方法時,其內部的約束是不完整的,具體表現為有的子視圖已經完成了布局,而有的子視圖正在或者還未進行布局.為了保證方法的正確執行,我們必須調用父類的layoutSuviews,不能在其內部調用setNeedsUpdateConstraints(時機太晚了,已經進入了布局階段),并且不能隨意地更改約束,防止與其他視圖層次相關的約束的改變.

Interacting Legacy Layout (處理系統遺留的布局)

  1. 當我們用代碼使用Autolayout給視圖添加約束時,要時刻留意將translatesAutoresizingMaskIntoConstraints`設為NO,否則添加完約束后就會出現一下約束警告日志.
    interactConstraint.png
    .這是由于系統默認設置了Yes,給視圖添加的固定約束而與我們自己后添加的約束產生了沖突,導致不能同時滿足約束條件進行布局.(IB里自動將此屬性值設置為No).
  2. 如果想要自己設置內部視圖的Frame時,重寫layoutSuviews,在此方法里設置,切記不要忘記調用父類方法.

Constraint Creation

關于系統自帶API進行約束的創建方式一直以來都被我們詬病,設個約束出要那么大坨代碼(差評~)...但如果了解使用VFL創建約束的話還是很優雅的,只是實現的約束有所限制.而現在iOS9提供了新的約束創建方式,讓開發者可以更加明了,快速地創建約束.

constraintCreate.png

通過查看UIView的頭文件,可以看到viewanchor屬性都定義在一個名為UIViewLayoutConstraintCreationUIView分類中.

// NSLayoutXAxisAnchor 類型表示在X軸上的約束
leadingAnchor 
trailingAnchor
leftAnchor 
rightAnchor
centerXAnchor

// NSLayoutXAxisAnchor 類型表示在Y軸上的約束
topAnchor
bottomAnchor
centerYAnchor
firstBaselineAnchor
lastBaselineAnchor 

// NSLayoutDimension 類型表示尺寸相關的約束
widthAnchor 
heightAnchor

初次之外,新的NSLayoutAnchor類的文件里提供了一系列進行相關視圖進行約束設置的方法,這里就不一一介紹,可以Command + R進行看看.

Constraining Negative Space

這里所提到的關于對多個視圖進行等間距或者同時居中的情況下,以前的做法就是創建假的UIView僅僅為提供約束來達成目的,而現在有了UILayoutGuide對象其表示著一個可以使用Autolayout的布局矩形區域,可以通過視圖的分類方法addLayoutGuide添加guide,來充當之前僅僅提供約束的假視圖,作用于Autolayout.具體的話就舉一個實現讓三個按鈕等間距排列,結合代碼和圖應該能剛好理解點.

Screen Shot 2015-12-12 at 10.31.31 PM.png

    //UIButton *saveButton;
    //UIButton *cancelButton;
    //UIButton *clearButton;
    
    UILayoutGuide *space1 = [[UILayoutGuide alloc]init];
    [saveButton addLayoutGuide:space1];
    UILayoutGuide *space2 = [[UILayoutGuide alloc]init];
    [cancelButton addLayoutGuide:space2];

    NSLayoutConstraint *spaceConstraint = [space1.widthAnchor constraintEqualToAnchor:space2.widthAnchor];
    NSLayoutConstraint *constraintOne = [saveButton.rightAnchor constraintEqualToAnchor: space1.leftAnchor];
    NSLayoutConstraint *constraintTow = [cancelButton.leftAnchor constraintEqualToAnchor:space1.rightAnchor];
    NSLayoutConstraint *constraintThree = [cancelButton.rightAnchor constraintEqualToAnchor:space2.leftAnchor];
    NSLayoutConstraint *constraintFour = [clearButton.leftAnchor constraintEqualToAnchor:space2.rightAnchor];
    
    [NSLayoutConstraint activateConstraints:@[spaceConstraint, constraintOne, constraintTow, constraintThree, constraintFour]];

Unsatisfiable Constraints

想要了解Unsatisfiable的具體的相關約束以及關聯對象,就必須要理解輸出的約束警告日志.

understandLog3.png

現在允許給約束或者視圖添加約束標識符identifier字符串屬性,將會在日志輸出中顯示,極大讓日志內容更加清晰,讓開發者快速找到存在問題的約束和視圖.

Resolving Ambiguity

出現Ambigous Layout 警告時表示著約束間存在沖突,而造成約束沖突的原因主要有:

  1. 約束太少
  2. 約束的優先級沖突

針對調試解決辦法直接上圖(...懶了??)
resolvingAmbiguity5.png

總結

本視頻從約束布局的生命周期到如何Debug布局問題,對Autolayout引擎的工作流程做了充分了說明和Demo演示,也告訴了我們一些在使用Autolayout中值得注意的地方,對工作中使用和處理Autolayout問題有很大的幫助,作為唯一有字幕(當然是英文的??)的介紹Autolayout的WWDC Session是值得一看.如果還有說明問題,歡迎留言,一起探討.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容