iOS layoutSubviews相關

layoutSubviews 這個方法剂府,默認沒有做任何事情,需要子類進行重寫剃盾。

(This method) Lays out subviews.
Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews DO NOT offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
以上節(jié)選自 UIView Class Reference
Whenever the size of a view changes, UIKit applies the autoresizing behaviors of that view’s subviews and THEN calls the layoutSubviews method of the view to let it make manual changes. You can implement the layoutSubviews method in custom views when the autoresizing behaviors by themselves DO NOT yield the results you want. Your implementation of this method can do any of the following:
Adjust the size and position of any immediate subviews.
Add or remove subviews or Core Animation layers.
Force a subview to be redrawn by calling its setNeedsDisplay or setNeedsDisplayInRect: method.
One place where applications often lay out subviews manually is when implementing a large scrollable area. Because it is impractical to have a single large view for its scrollable content, applications often implement a root view that contains a number of smaller tile views. Each tile represents a portion of the scrollable content. When a scroll event happens, the root view calls its setNeedsLayout method to initiate a layout change. Its layoutSubviews method then repositions the tile views based on the amount of scrolling that occurred. As tiles scroll out of the view’s visible area, the layoutSubviews method moves the tiles to the incoming edge, replacing their contents in the process.
以上節(jié)選自 View Programming Guide for iOS

根據(jù)官方文檔的描述腺占,可以知道 layoutSubviews 主要是為了讓我們?nèi)崿F(xiàn)UIView的策略來布局以及排列等淤袜,這樣就可以保證我們在需要新的布局方案的時候,父類UIView 會按照我們制定的方案去布局衰伯。我們在某個類的內(nèi)部調(diào)整子視圖位置時铡羡,需要調(diào)用。反過來的意思就是說:如果你想要在外部設置 sub views 的位置意鲸,就不要重寫烦周。而且,layoutSubviews 方法只能被系統(tǒng)觸發(fā)調(diào)用怎顾,不可以手動去調(diào)用读慎。 要引起該方法的調(diào)用,可以調(diào)用 UIView 的 setNeedsLayout 方法來標記一個 UIView杆勇。這樣一來贪壳,在 UI 線程的下次繪制循環(huán)中,系統(tǒng)便會調(diào)用該 UIView 的 layoutSubviews 方法蚜退。

在蘋果的官方文檔中強調(diào):

You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.
layoutSubviews, 當我們在某個類的內(nèi)部調(diào)整子視圖位置時闰靴,需要調(diào)用;如果你想要在外部設置subviews的位置钻注,就不要重寫蚂且。

layoutSubviews 默認沒有做任何事情,既然我不能手動直接調(diào)用該方法幅恋,那在什么時候杏死、何種條件下這個方法會被調(diào)用呢?

Stackoverflow 上已經(jīng)有相關的討論了(作者在他的博客上有更詳細的描述)捆交,并且有一位朋友給出了很不錯的解答:

  1. init does not cause layoutSubviews to be called (duh)
  2. addSubview causes layoutSubviews to be called on the view being added, the view it’s being added to (target view), and all the subviews of the target
  3. view setFrame intelligently calls layoutSubviews on the view having its frame set only if the size parameter of the frame is different
  4. scrolling a UIScrollView causes layoutSubviews to be called on the scrollView, and its superview
  5. rotating a device only calls layoutSubview on the parent view (the responding viewControllers primary view)
  6. Resizing a view will call layoutSubviews on its superview

翻譯:

  1. init初始化不會觸發(fā)layoutSubviews 但是是用initWithFrame 進行初始化時淑翼,當rect的值不為CGRectZero時,也會觸發(fā)
  2. addSubview會觸發(fā)layoutSubviews
  3. 設置view的Frame會觸發(fā)layoutSubviews,當然前提是frame的值設置前后發(fā)生了變化
  4. 滾動一個UIScrollView會觸發(fā)layoutSubviews
  5. 旋轉(zhuǎn)Screen會觸發(fā)父UIView上的layoutSubviews事件
  6. 改變一個UIView大小的時候也會觸發(fā)父UIView上的layoutSubviews事件

iOS 中 layout 的相關方法:

  • layoutSubviews
  • layoutIfNeeded
  • setNeedsLayout
  • setNeedsDisplay
  • drawRect
  • sizeThatFits
  • sizeToFit

當然這并不齊全品追。

1. setNeedsLayout方法
標記為需要重新布局玄括,異步調(diào)用layoutIfNeeded刷新布局,不立即刷新肉瓦,但layoutSubviews一定會被調(diào)用
2. layoutIfNeeded方法
如果有需要刷新的標記遭京,立即調(diào)用layoutSubviews進行布局;如果沒有標記泞莉,不會調(diào)用layoutSubviews哪雕;如果要立即刷新,要先調(diào)用[view setNeedsLayout]鲫趁,把標記設為需要布局斯嚎,然后馬上調(diào)用[view layoutIfNeeded],實現(xiàn)布局饮寞。在視圖第一次顯示之前孝扛,標記總是“需要刷新”的列吼,可以直接調(diào)用[view layoutIfNeeded]

3. 重繪
drawRect方法:重寫此方法幽崩,執(zhí)行重繪任務
setNeedsDisplay方法:標記為需要重繪苦始,異步調(diào)用drawRect
setNeedsDisplayInRect方法:標記為需要局部重繪

4. sizeToFit
sizeToFit會自動調(diào)用sizeThatFits方法;

sizeToFit不應該在子類中被重寫慌申,應該重寫sizeThatFits

sizeThatFits傳入的參數(shù)是receiver當前的size陌选,返回一個適合的size

sizeToFit可以被手動直接調(diào)用

sizeToFit和sizeThatFits方法都沒有遞歸,對subviews也不負責蹄溉,只負責自己

Tips:

  1. layoutSubviews對subviews重新布局

  2. layoutSubviews方法調(diào)用先于drawRect

  3. setNeedsLayout在receiver標上一個需要被重新布局的標記咨油,在系統(tǒng)runloop的下一個周期自動調(diào)用layoutSubviews

  4. layoutIfNeeded方法如其名,UIKit會判斷該receiver是否需要layout.根據(jù)Apple官方文檔,layoutIfNeeded方法應該是這樣的

  5. layoutIfNeeded遍歷的不是superview鏈柒爵,應該是subviews鏈

  6. drawRect是對receiver的重繪役电,能獲得context

  7. setNeedDisplay在receiver標上一個需要被重新繪圖的標記,在下一個draw周期自動重繪棉胀,iphone device的刷新頻率是60hz法瑟,也就是1/60秒后重繪

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市唁奢,隨后出現(xiàn)的幾起案子霎挟,更是在濱河造成了極大的恐慌,老刑警劉巖麻掸,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酥夭,死亡現(xiàn)場離奇詭異,居然都是意外死亡脊奋,警方通過查閱死者的電腦和手機熬北,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诚隙,“玉大人讶隐,你說我怎么就攤上這事∽羁” “怎么了整份?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長籽孙。 經(jīng)常有香客問我烈评,道長,這世上最難降的妖魔是什么犯建? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任讲冠,我火速辦了婚禮,結(jié)果婚禮上适瓦,老公的妹妹穿的比我還像新娘竿开。我一直安慰自己谱仪,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布否彩。 她就那樣靜靜地躺著疯攒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪列荔。 梳的紋絲不亂的頭發(fā)上敬尺,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音贴浙,去河邊找鬼砂吞。 笑死,一個胖子當著我的面吹牛崎溃,可吹牛的內(nèi)容都是我干的蜻直。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼袁串,長吁一口氣:“原來是場噩夢啊……” “哼概而!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起般婆,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤到腥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蔚袍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乡范,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年啤咽,在試婚紗的時候發(fā)現(xiàn)自己被綠了晋辆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡宇整,死狀恐怖瓶佳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鳞青,我是刑警寧澤霸饲,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站臂拓,受9級特大地震影響厚脉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胶惰,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一傻工、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦中捆、人聲如沸鸯匹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殴蓬。三九已至,卻和暖如春臂容,著一層夾襖步出監(jiān)牢的瞬間科雳,已是汗流浹背根蟹。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工脓杉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人简逮。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓球散,卻偏偏與公主長得像,于是被迫代替她去往敵國和親散庶。 傳聞我的和親對象是個殘疾皇子蕉堰,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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