WWDC之Mysteries of Auto Layout Part 2

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

資源

內(nèi)容

The Layout Cycle

layoutCycle.png

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

Constraints Change

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

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

    [NSLayoutConstraint activateConstraints:]
    [NSLayoutConstraint deactivateConstraints:]
    // 參數(shù)為NSLayoutConstraint對象的數(shù)組

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

equal.png

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

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

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

Deferred Layout Pass

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

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

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

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

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

Constraint Creation

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

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

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

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的具體的相關約束以及關聯(lián)對象,就必須要理解輸出的約束警告日志.

understandLog3.png

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

Resolving Ambiguity

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

  1. 約束太少
  2. 約束的優(yōu)先級沖突

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

總結(jié)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贼涩,一起剝皮案震驚了整個濱河市股囊,隨后出現(xiàn)的幾起案子逊桦,更是在濱河造成了極大的恐慌博秫,老刑警劉巖脚祟,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件决乎,死亡現(xiàn)場離奇詭異拓哟,居然都是意外死亡浙滤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門躯概,熙熙樓的掌柜王于貴愁眉苦臉地迎上來登钥,“玉大人,你說我怎么就攤上這事娶靡∧晾危” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵姿锭,是天一觀的道長塔鳍。 經(jīng)常有香客問我,道長呻此,這世上最難降的妖魔是什么轮纫? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮焚鲜,結(jié)果婚禮上掌唾,老公的妹妹穿的比我還像新娘。我一直安慰自己忿磅,他們只是感情好糯彬,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葱她,像睡著了一般撩扒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吨些,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天搓谆,我揣著相機與錄音炒辉,去河邊找鬼。 笑死挽拔,一個胖子當著我的面吹牛辆脸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播螃诅,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼啡氢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了术裸?” 一聲冷哼從身側(cè)響起倘是,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袭艺,沒想到半個月后搀崭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡猾编,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年瘤睹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片答倡。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡轰传,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瘪撇,到底是詐尸還是另有隱情获茬,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布倔既,位于F島的核電站恕曲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏渤涌。R本人自食惡果不足惜佩谣,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望实蓬。 院中可真熱鬧稿存,春花似錦、人聲如沸瞳秽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽练俐。三九已至,卻和暖如春冕臭,著一層夾襖步出監(jiān)牢的瞬間腺晾,已是汗流浹背燕锥。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留悯蝉,地道東北人归形。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像鼻由,于是被迫代替她去往敵國和親暇榴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

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