談談layoutSubviews和drawRect

首先兩個方法都是異步執行,layoutSubviews方便數據計算,drawRect方便視圖重繪。

layoutSubviews

1

今天在寫程序時候遇見layoutSubviews觸發時候引起的問題。特來總結一下什么時候會觸發layoutSubviews:layoutSubviews在以下情況下會被調用:
1、init初始化不會觸發layoutSubviews但是是用initWithFrame 進行初始化時,當rect的值不為CGRectZero時,也會觸發
2、addSubview會觸發layoutSubviews 但frame !={0,0,0,0}
3、設置view的Frame會觸發layoutSubviews,當然前提是frame的值設置前后發生了變化view的with,height發現變化才會觸發layoutSubviews,original. x ,original. y變化不會觸發layoutSubviews
4、滾動一個UIScrollView會觸發layoutSubviews
5、旋轉Screen會觸發父UIView上的layoutSubviews事件
6、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件
http://blog.csdn.net/s133315202/article/details/47108531

2

原文
http://www.superqq.com/blog/2015/07/27/ioskai-fa-zhi-layoutsubviewsde-zuo-yong-he-diao-yong-ji-zhi/

在UIView里面有一個方法layoutSubviews,這個方法具體作用是什么呢?

- (void)layoutSubviews;    // override point. called by layoutIfNeeded automatically. As of iOS 6.0, when constraints-based layout is used the base implementation applies the constraints-based layout, otherwise it does nothing.

官方文檔解釋

我們先來看看蘋果官方文檔的解釋:

The default implementation of this method does nothing on iOS 5.1 and earlier. Otherwise, the default implementation uses any constraints you have set to determine the size and position of any 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.

You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.

最后一段說,不要直接調用此方法。如果你想強制更新布局,你可以調用setNeedsLayout方法;如果你想立即數顯你的views,你需要調用layoutIfNeeded方法。

layoutSubviews作用

layoutSubviews是對subviews重新布局。比如,我們想更新子視圖的位置的時候,可以通過調用layoutSubviews方法,既可以實現對子視圖重新布局。

layoutSubviews默認是不做任何事情的,用到的時候,需要在子類進行重寫。

layoutSubviews以下情況會被調用

蘋果官方文檔已經強調,不能直接調用layoutSubviews對子視圖進行重新布局。那么,layoutSubviews什么情況下會被調用呢?通過百度搜索,發現以下幾種情況layoutSubviews會被調用。

1.直接調用setLayoutSubviews。(這個在上面蘋果官方文檔里有說明)
2.addSubview的時候。
3.當view的frame發生改變的時候。
4.滑動UIScrollView的時候。
5.旋轉Screen會觸發父UIView上的layoutSubviews事件。
6.改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件。
7.init初始化不會觸發layoutSubviews。

我簡單測試了一下,上面基本都會被調用。 注意:

當view的fram的值為0的時候,`addSubview`也不會調用`layoutSubviews`的。

layoutSubviews方法在對子類視圖進行布局的時候非常方便。可以自己動手,深入理解layoutSubviews的調用機制。

3

原文 http://blog.csdn.net/u013243469/article/details/41513129
layoutSubviews是UIView中的屬性方法,即只要繼承于UIView,就可以使用這個方法,這個方法也很強大,以下是他的觸發時機:
1、init初始化不會觸發layoutSubviews
2、addSubview會觸發layoutSubviews
3、設置view的Frame會觸發layoutSubviews,當然前提是frame的值設置前后發生了變化
4、滾動一個UIScrollView會觸發layoutSubviews
5、旋轉Screen會觸發父UIView上的layoutSubviews事件
6、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件

在這些觸發情況下,我們就可以妙用他,比如說改變數據等等,這是個很不錯的方法 而且我們也可以手動調用,即

[self setNeedsLayout];

注意:調用layoutSubviews,也需要調用它的父類方法,即

[super layoutSubviews]

傳說如果不調用的話會出現奇怪的問題。

4

原文
博客專區 > 董桉遠的博客 > 董桉遠的博客詳情iOS layoutSubviews 什么時候會被調用

init 方法不會調用layoutSubviews
addSubview 會觸發target view(被添加view的view)和其subviewlayoutSubviews方法
setFrame 只有當設置的frame的參數的size與原來的size不同,才會觸發其view的layoutSubviews方法
滑動 UIScrollView 會調用scrollview及scrollview上的view的layoutSubviews方法
**旋轉設備 **只會調用VC的view的layoutSubviews方法
removeFromSuperview 只會調用superview的 layoutSubviews方法

5

http://bbs.csdn.net/topics/390992153
http://www.cnblogs.com/ioriwellings/archive/2012/12/27/2835340.html
http://qa.blog.163.com/blog/static/1901470022015101124723108
http://www.knowsky.com/883371.html
全面http://www.lxweimin.com/p/d1ce00f08b7f

drawRect

1

drawRect在以下情況下會被調用:
1、如果在UIView初始化時沒有設置rect大小,將直接導致drawRect不被自動調用。drawRect 掉用是在Controller->loadView,?Controller->viewDidLoad?兩方法之后掉用的.所以不用擔心在 控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設置一些值給View(如果這些View?draw的時候需要用到某些變量 值).
2、該方法在調用sizeToFit后被調用,所以可以先調用sizeToFit計算出size。然后系統自動調用drawRect:方法。
3、通過設置contentMode屬性值為UIViewContentModeRedraw。那么將在每次設置或更改frame的時候自動調用drawRect:。
4、直接調用setNeedsDisplay,或者setNeedsDisplayInRect:觸發drawRect:,但是有個前提條件是rect不能為0。
以上1,2推薦;而3,4不提倡
drawRect方法使用注意點:
1、 若使用UIView繪圖,只能在drawRect:方法中獲取相應的contextRef并繪圖。如果在其他方法中獲取將獲取到一個invalidate 的ref并且不能用于畫圖。drawRect:方法不能手動顯示調用,必須通過調用setNeedsDisplay?或 者?setNeedsDisplayInRect,讓系統自動調該方法。
2、若使用calayer繪圖,只能在drawInContext:?中(類似于drawRect)繪制,或者在delegate中的相應方法繪制。同樣也是調用setNeedDisplay等間接調用以上方法
3、若要實時畫圖,不能使用gestureRecognizer,只能使用touchbegan等方法來調用setNeedsDisplay實時刷新屏幕

2

原文http://blog.sina.com.cn/s/blog_afb4d07f0101iamg.html

setNeedsDisplay和setNeedsLayout兩個方法都是異步的,setNeedsDisplay會自動調用drawRect,而setNeedsLayout會自動調用layoutSubviews。

layoutSubviews方便數據計算,drawRect方便視圖重繪。

假設我們采用的是直接調用drawRect的機制,先考慮這樣一個問題 ,,現在有兩個UIViewController A和B,A為當前view的viewController,如果此時在A中調用[B.view drawRect],這樣B的view無論如何都會調用drawRect的方法重新繪制一遍,這樣問題就出來了,有必要嗎,畢竟現在顯示的是A中的view!B重新繪制一遍就調用了drawRect中的方法,完全是在浪費系統資源啊,而通過setNeedsDisplay,ios就會很聰明的判斷出不需要調用drawRect的方法,這樣就避免了資源的重復調用! 同理,setNeedsLayout也采用了同樣的機制來避免資源的重復利用!

layoutSubviews在以下情況下會被調用:

1、init初始化不會觸發layoutSubviews。
2、addSubview會觸發layoutSubviews。
3、設置view的Frame會觸發layoutSubviews,當然前提是frame的值設置前后發生了變化。
4、滾動一個UIScrollView會觸發layoutSubviews。
5、旋轉Screen會觸發父UIView上的layoutSubviews事件。
6、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件。
7、直接調用setLayoutSubviews。

drawRect在以下情況下會被調用:

1、如果在UIView初始化時沒有設置rect大小,將直接導致drawRect不被自動調用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 兩方法之后掉用的.所以不用擔心在 控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設置一些值給View(如果這些View draw的時候需要用到某些變量 值).
2、該方法在調用sizeToFit后被調用,所以可以先調用sizeToFit計算出size。然后系統自動調用drawRect:方法。
3、通過設置contentMode屬性值為UIViewContentModeRedraw。那么將在每次設置或更改frame的時候自動調用drawRect:。
4、直接調用setNeedsDisplay,或者setNeedsDisplayInRect:觸發drawRect:,但是有個前提條件是rect不能為0。以上1,2推薦;而3,4不提倡

drawRect方法使用注意點:

1、 若使用UIView繪圖,只能在drawRect:方法中獲取相應的contextRef并繪圖。如果在其他方法中獲取將獲取到一個invalidate 的ref并且不能用于畫圖。drawRect:方法不能手動顯示調用,必須通過調用setNeedsDisplay 或 者 setNeedsDisplayInRect,讓系統自動調該方法。
2、若使用calayer繪圖,只能在drawInContext: 中(類似魚drawRect)繪制,或者在delegate中的相應方法繪制。同樣也是調用setNeedDisplay等間接調用以上方法
3、若要實時畫圖,不能使用gestureRecognizer,只能使用touchbegan等方法來掉用setNeedsDisplay實時刷新屏幕

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容