iOS中的Auto Layout和Frame

1 iOS常用的布局方式

iOS中界面有三種布局方式:Frame,Autoresizing Masks和Auto Layout沃暗。

一般而言Frame是最隨心所欲的魁兼,你可以做你任何想要的改變坐搔,但是同時也是最繁瑣的藏研,一旦布局發(fā)生改變你要更改所有的相關視圖的Frame。Autoresizing Masks定義了父視圖frame變化時子視圖的frame如何變化概行,這簡化了視圖外部布局變化時內部視圖變化的工作量蠢挡。Auto Layout使用約束來表示視圖間的相應關系,不論是外部變化還是內部變化凳忙,視圖都可以動態(tài)相應业踏,大大簡化了我們的布局方式。

以上是三種布局方式的主要特點涧卵,但也不絕對勤家,比如使用Frame的時候我們也會根據(jù)其他視圖的left,right去編寫布局柳恐,這樣也有了視圖間的相互關系的意味伐脖。使用Auto Layout時的leading,trailing很多時候都是一個常量并不符合我們的要求乐设,還要在視圖加載或者變化過程中去修改值才能達到動態(tài)響應變化的效果讼庇。所以使用哪種布局方式好并沒有一個定論,而且我也支持在特定的情況下使用有優(yōu)勢的布局方式近尚。這樣就造成了對于生命力較長的項目會出現(xiàn)多種方式并存的局面蠕啄,本文章主要講對于Frame和Auto Layout混用情況下的一些避坑策略。

2 視圖加載過程

要混用Frame和Auto Layout肿男,必須要搞清楚他們的作用時間和有效范圍介汹,這和視圖的加載過程有很大的關系。我們在controller視圖上面用auto layout添加了一個subview舶沛,并在各個系統(tǒng)調用聲明周期方法中做了打印處理嘹承,結果如下:

viewDidLoad   
viewWillAppear 
viewWillLayoutSubviews(1)  
-updateConstraints   
updateViewConstraints
viewWillLayoutSubviews(2)
viewDidLayoutSubviews   
-layoutSubviews   
-drawRect  
viewDidAppear   

其中前面帶有“-”符號的表示的是subview視圖的打印。對于viewWillLayoutSubviews出現(xiàn)的順序根據(jù)使用的布局方式會有所區(qū)別如庭,使用Frame時出現(xiàn)為viewWillLayoutSubviews(1)位置叹卷,使用Auto Layout時出現(xiàn)在viewWillLayoutSubviews(2)位置。

Auto Layout的作用范圍是從第三個方法-updateConstraints開始直到viewDidLayoutSubviews完成坪它,在這期間系統(tǒng)是通過view上的約束來計算view上的布局骤竹。一般我們都是在viewDidLoad里面編寫頁面布局代碼,如果這時對一個視圖同時使用了Auto Layout和Frame往毡,我們會發(fā)現(xiàn)frame無效蒙揣,就是因為這時布局是按照約束來計算的。如果視圖的frame在布局過程中發(fā)生了改變(比如initWithFrame开瞭,使用xib都會給予初始值懒震,但實際布局時我們可能想要更改)罩息,這時如果想獲取視圖的準確frame值,在viewWillAppear中是不行的个扰,只能在自動布局生效后獲取到瓷炮,即我們可以再viewDidLayoutSubviews和viewDidAppear中獲取frame的準確值。由上述結果也可以得出递宅,系統(tǒng)的布局是優(yōu)先使用Auto Layout的娘香,但是布局的最終結果卻是將約束轉化成視圖的frame,理解了這一點對于布局方式的選用也很重要办龄。

要想修改布局烘绽,必須要在Auto Layout結束之后才會起作用,否則會被系統(tǒng)將我們的布局按照Auto Layout重新刷新土榴。從上面我們可以看到诀姚,我們可以在子視圖的-layoutSubviews和-drawRect方法里面修改子視圖的布局,但是一般視圖為了重用不會在自己的類里面將frame寫死玷禽,這樣我們只有通過controller的viewDidLayoutSubviews和viewDidAppear方法修改視圖的frame。但是這樣也有問題呀打,在viewDidAppear里面修改布局矢赁,我們可以看到一個明顯的延遲,系統(tǒng)調用次序使然贬丛,我們無法去改變撩银。

所以我的建議就是不要對同一個視圖同時使用Frame和Auto Layout去控制同一個視圖。如果一個視圖使用了某種布局方式豺憔,那么盡量保持統(tǒng)一中方式改變布局额获。

3 不同布局方式混用

不是說可以混用嗎,怎么又突然說對同一個視圖使用一種方式恭应?那我們來定義一下混用方式: 父視圖A包含子視圖B抄邀、C,子視圖B包含子視圖B1昼榛、B2境肾,子視圖C包含子視圖C1和C2。如圖:


對于B和C我們可以使用Frame的方式布局其在父視圖A中的位置和大小胆屿,但是對于B1和B2奥喻,我們可以使用Auto Layout的方式來布局其在父視圖B中的尺寸和位置關系。這就是我理解的混用非迹,對于同一層級的視圖使用相同的布局方式环鲤,對于不同層級的使用可以使用其他布局方式。

那么它的意義是什么呢憎兽?不同view的復雜度決定了我們采取哪種方式來對其布局冷离,我們在開發(fā)中有可能會遇到某些流式的布局吵冒,我們用Auto Layout可以行云流水,但是對于某個視圖當中極其復雜的小控件的布局酒朵,Auto Layout顯然要寫不少的一大段桦锄,當兩者組合時也就是混用的意義所在。

4 使用過程中的坑

(1) 約束變化后視圖更新

有的時候我們更改約束后發(fā)現(xiàn)視圖并沒有變化蔫耽,這是因為約束改變后并沒有觸發(fā)視圖重新布局结耀。如果要重新布局,可以使用layoutIfNeeded()立即更新視圖布局匙铡,使用setNeedsLayout()在下個繪圖周期中觸發(fā)布局更新图甜。這兩個方法都會觸發(fā)layoutSubviews()方法。

(2)不要啟用NSAutoresizingMaskLayoutConstraint

蘋果iOS6之后推出了Auto Layout技術鳖眼,但是還想兼容原來的autoresizing黑毅,所以它將autoresizing轉化為了約束,轉化后的約束類型就是NSAutoresizingMaskLayoutConstraint钦讳,這就有可能導致系統(tǒng)為我們添加了許多我們無法預料的約束矿瘦。當我們添加的約束不,但是視圖顯示在界面上沒有任何問題愿卒,這是NSAutoresizingMaskLayoutConstraint幫我們自動補齊了約束缚去。在此情況下有可能出現(xiàn)frame不正確。所以我們在混用時不要開啟此屬性琼开,即設置其為NO易结。在storyboard上NSAutoresizingMaskLayoutConstraint默認為開啟,純代碼默認為關閉柜候。

總結:
(1)使用Auto Layout時NSAutoresizingMaskLayoutConstraint設置為NO搞动,設置完整清晰的約束。
(2)對同一層級視圖使用相同布局方式渣刷,對非同一層級視圖可以使用不同布局方式鹦肿。對同一視圖在同一布局時間段內不要同時使用不同的布局方式。
(3)搞清視圖布局飞主、繪制步驟狮惜,區(qū)分清楚Frame和Auto Layout的有效范圍,在合適的時機進行視圖布局變化碌识、更新和frame獲取碾篡。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市筏餐,隨后出現(xiàn)的幾起案子开泽,更是在濱河造成了極大的恐慌,老刑警劉巖魁瞪,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件穆律,死亡現(xiàn)場離奇詭異惠呼,居然都是意外死亡,警方通過查閱死者的電腦和手機峦耘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門剔蹋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辅髓,你說我怎么就攤上這事泣崩。” “怎么了洛口?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵矫付,是天一觀的道長。 經(jīng)常有香客問我第焰,道長买优,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任挺举,我火速辦了婚禮杀赢,結果婚禮上,老公的妹妹穿的比我還像新娘湘纵。我一直安慰自己葵陵,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布瞻佛。 她就那樣靜靜地躺著,像睡著了一般娇钱。 火紅的嫁衣襯著肌膚如雪伤柄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天文搂,我揣著相機與錄音适刀,去河邊找鬼。 笑死煤蹭,一個胖子當著我的面吹牛笔喉,可吹牛的內容都是我干的。 我是一名探鬼主播硝皂,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼常挚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了稽物?” 一聲冷哼從身側響起奄毡,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贝或,沒想到半個月后吼过,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锐秦,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年盗忱,在試婚紗的時候發(fā)現(xiàn)自己被綠了酱床。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡趟佃,死狀恐怖扇谣,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情揖闸,我是刑警寧澤揍堕,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站汤纸,受9級特大地震影響衩茸,放射性物質發(fā)生泄漏。R本人自食惡果不足惜贮泞,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一楞慈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啃擦,春花似錦囊蓝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至珠叔,卻和暖如春蝎宇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祷安。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工姥芥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人汇鞭。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓凉唐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親霍骄。 傳聞我的和親對象是個殘疾皇子台囱,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內容