iOS開發(fā)中诺凡,- (void)layoutSubviews{}方法及相關方法注意點K当础议惰!
文章著重介紹iOS開發(fā)中如果給subViews設置fram
layout相關的方法
- (void)layoutSubviews {};
- (void)layoutIfNeeded {};
- (void)setNeedsLayout {};
- (CGSize)sizeThatFits:(CGSize)size {};
- (void)sizeToFit {};
- (void)setNeedsDisplay {};
- (void)drawRect {};
一、-(void)layoutSubviews{}在以下情況下會被調(diào)用/被觸發(fā)乡恕?言询?
- 1俯萎、[self setNeedsLayout]
- 2、addSubview會觸發(fā)layoutSubviews
- 3运杭、設置view的Frame會觸發(fā)layoutSubviews夫啊,當然前提是frame的值設置前后發(fā)生了變化
- 4、滾動一個UIScrollView會觸發(fā)layoutSubviews
- 5辆憔、旋轉Screen會觸發(fā)父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的位置躁愿,就不要重寫叛本。)
1.1.什么時候,需要重寫- (void)layoutSubviews{}呢彤钟?来候?
- view是系統(tǒng)的,不需要重寫逸雹,如果view是自定義的营搅,需要重寫。
- -layoutSubviews方法:這個方法里面梆砸,默認沒有做任何事情转质,需要子類進行重寫,自定義view時帖世,手動重寫休蟹,這里面只能寫subview的frame限制。
1.2. 如何手動觸發(fā)這個方法(- (void)layoutSubviews{})日矫?
iOS開發(fā)中赂弓,開發(fā)者不能直接調(diào)用這個方法,系統(tǒng)默認不允許我們這樣哪轿,那怎么在需要的時候盈魁,手動觸發(fā)這個方法呢?下面提供兩個方法窃诉。杨耙。
- -(void)setNeedsLayout {};//作用:告之view,需要重新布局飘痛,在未來某個時間點系統(tǒng)異步觸發(fā)布局方法,且標記view.subViews需要重新布局珊膜。這個方法使用后,view不會立即刷新敦冬,但layoutSubviews{}一定會被調(diào)用.
- -(void)layoutIfNeeded {};//如果:有需要刷新的標記辅搬,立即調(diào)用layoutSubviews進行布局(如果沒有標記,不會調(diào)用layoutSubviews)
- 開發(fā)中示例:
- 1.需要立即刷新view的frame
[self layoutIfNeeded];//更改最新的標記
- 2.在初始化方法init這類方法里、或view第一次顯示之前堪遂,系統(tǒng)默認標記“需要刷新”介蛉,故此:這些地方我們可直接調(diào)用-(void)layoutIfNeeded{} eg:[view layoutIfNeeded]
- 3.需要多次修改布局,修改完每處布局后溶褪,還需要下次修改來完善布局币旧,那這次布局就需要做一下標記
//假設需要4出更改布局 - (void)change_01~03//1-3處更改,用setNeedsLayout標記 { [self setNeedsLayout];//更改最新的標記 } - (void)change_04//等到所有布局晚上后 { [self layoutIfNeeded];//更改最新的標記 }
- 1.需要立即刷新view的frame
二猿妈、重繪制相關方法
開發(fā)者:重新繪制一個嶄新的view吹菱,需要重寫-(void)drawRect:(CGRect)rect {}
1.1.什么時候,需要重寫-(void)drawRect:(CGRect)rect {}呢彭则?鳍刷?
- 取決開發(fā)者的個人愛好。
1.2. 如何手動觸發(fā)這個方法(- (void) drawRect:(CGRect)rect{})俯抖?
iOS開發(fā)中输瓜,開發(fā)者不能直接調(diào)用這個方法,系統(tǒng)默認不允許我們這樣芬萍,那怎么在需要的時候尤揣,手動觸發(fā)這個方法呢?下面提供兩個方法柬祠。北戏。
- -(void) setNeedsDisplay {};//作用:標記為需要重繪,異步調(diào)用drawRect.
- -(void) setNeedsDisplayInRect:(CGRect)invalidRect {};//標記為需要局部重繪.
三漫蛔、其他與布局subViews.frame相關方法
- (CGSize)sizeThatFits:(CGSize)size {};
- (void)sizeToFit {};
注意點:1.無論什么時候調(diào)用sizeToFit嗜愈,其底層實質sizeToFit自動調(diào)用sizeThatFits方法。2. -(void)sizeToFit {}不應該在子類中被重寫莽龟,應該重寫 -(CGSize)sizeThatFits:(CGSize)size {}芝硬,
- -(CGSize)sizeThatFits:(CGSize)size {}//返回值為開發(fā)者給定的size,參數(shù)size:是現(xiàn)在view現(xiàn)有的size轧房。//開發(fā)者可自定義控件實質返回的大小。
3.1.sizeToFit的用途绍绘?
- 在開發(fā)中奶镶,經(jīng)常用到UIButton,UIBarButtonItem,UITableView的組頭,組尾,表頭,表尾.類似控件。他們無需我們設置frame陪拘,只需要制定size厂镇。這個時候,我們可以通過直接調(diào)用sizeToFit是這類控件根據(jù)自身的內(nèi)容左刽,獲取自身的大小捺信,顯示出來。
3.2. sizeThatFits的用途?
- 在實際開發(fā)中這個方法一般沒有什么用途迄靠,因為它不需要我們手動調(diào)用秒咨。其次:我們都很相信蘋果,會給我們返回合理的size掌挚。
- 除非:自定義view雨席,重寫它,限制自身view的大小吠式。方便外層調(diào)用sizeToFit時陡厘,view顯示的大小是固定的(you給定的size)
3.3.注意:
- sizeToFit和sizeThatFits方法都沒有遞歸,對subviews也不負責特占,只負責自己
補充:
- drawRect是對receiver的重繪糙置,能獲得context
- layoutSubviews對subviews重新布局
- layoutSubviews方法調(diào)用先于drawRect
- setNeedsLayout在receiver標上一個需要被重新布局的標記,在系統(tǒng)runloop的下一個周期自動調(diào)用layoutSubviews(iphone device的刷新頻率是60hz是目,也就是(1/60)秒后重繪)
- layoutIfNeeded方法如其名谤饭,UIKit會判斷該receiver是否需要layout.如需要,無需等runloop的下一個周期胖笛,而是立即馬上更新
- layoutIfNeeded遍歷的不是superview鏈网持,應該是subviews鏈
后期會更新自動布局相關方法-(void)updateConstraints
- (void)updateConstraints{}
- (BOOL)needsUpdateConstraints{}
- (void)setNeedsUpdateConstraints{}