1.layoutSubviews
官方說明:
這個(gè)方法季眷,默認(rèn)沒有做任何事情余蟹,子類可以根據(jù)需要覆蓋此方法,以執(zhí)行其子視圖的更精確布局瘟裸。
您不應(yīng)該直接調(diào)用此方法客叉。 如果要強(qiáng)制進(jìn)行布局更新,請(qǐng)?jiān)谙麓卫L圖更新之前調(diào)用setNeedsLayout方法话告。
如果要立即更新視圖的布局兼搏,請(qǐng)調(diào)用layoutIfNeeded方法。
調(diào)用時(shí)機(jī):
1.init初始化不會(huì)觸發(fā)layoutSubviews沙郭;但是是用initWithFrame 進(jìn)行初始化時(shí)佛呻,當(dāng)rect的值不為CGRectZero時(shí), addSubview也會(huì)觸發(fā)
2.addSubview會(huì)觸發(fā)layoutSubviews
3.設(shè)置view的Frame會(huì)觸發(fā)layoutSubviews,當(dāng)然前提是frame的值設(shè)置前后發(fā)生了變化(因此在layoutSubviews中設(shè)置frame不會(huì)造成循環(huán));
4.滾動(dòng)一個(gè)UIScrollView會(huì)觸發(fā)layoutSubviews
5.旋轉(zhuǎn)Screen會(huì)觸發(fā)父UIView上的layoutSubviews事件
6.單純改變一個(gè)UIView大小的時(shí)候也會(huì)觸發(fā)父UIView上的layoutSubviews事件
7.setNeedsLayout方法(異步)病线、-layoutIfNeeded方法(馬上)會(huì)調(diào)用layoutSubviews進(jìn)行布局
總結(jié):layoutSubviews, 當(dāng)我們?cè)谀硞€(gè)類的內(nèi)部調(diào)整子視圖位置時(shí)吓著,需要調(diào)用。反過來的意思就是說:如果你想要在外部設(shè)置subviews的位置送挑,就不要重寫绑莺。
-layoutSubviews方法:這個(gè)方法,默認(rèn)沒有做任何事情惕耕,需要子類進(jìn)行重寫
-setNeedsLayout方法: 標(biāo)記為需要重新布局纺裁,異步調(diào)用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定會(huì)被調(diào)用
-layoutIfNeeded方法:如果欺缘,有需要刷新的標(biāo)記栋豫,立即調(diào)用layoutSubviews進(jìn)行布局(如果沒有標(biāo)記,不會(huì)調(diào)用layoutSubviews)
如果要立即刷新谚殊,要先調(diào)用[view setNeedsLayout]丧鸯,把標(biāo)記設(shè)為需要布局,然后馬上調(diào)用[view layoutIfNeeded]嫩絮,實(shí)現(xiàn)布局丛肢。
layoutSubviews方法調(diào)用先于drawRect
2.drawRect:(CGRect)rect執(zhí)行重繪任務(wù)
可以在UIView(UIViewRendering)的方法- (void)drawRect:(CGRect)rect;中去繪制一些我們所需要的圖形,如虛線絮记、圓形摔踱、方形以及曲線等等圖形 ,重寫此方法怨愤,執(zhí)行重繪任務(wù)。
調(diào)用時(shí)機(jī):
1蛹批、如果在UIView初始化時(shí)沒有設(shè)置rect大小撰洗,將直接導(dǎo)致drawRect不被自動(dòng)調(diào)用;在子類初始化時(shí)調(diào)用- (instancetype)initWithFrame:(CGRect)frame方法腐芍,且frame不為CGRectZero時(shí)會(huì)調(diào)用
2差导、該方法在調(diào)用sizeThatFits后被調(diào)用,所以可以先調(diào)用sizeToFit計(jì)算出size猪勇。然后系統(tǒng)自動(dòng)調(diào)用drawRect:方法设褐。
3、通過設(shè)置contentMode屬性值為UIViewContentModeRedraw泣刹。那么將在每次設(shè)置或更改frame的時(shí)候自動(dòng)調(diào)用drawRect:助析。
4、直接調(diào)用setNeedsDisplay椅您,或者setNeedsDisplayInRect:觸發(fā)drawRect:外冀,但是有個(gè)前提條件是rect不能為0.
5、drawRect是在Controller->loadView, Controller->viewDidLoad之后會(huì)自動(dòng)調(diào)用掀泳,調(diào)用時(shí)機(jī)是在viewWillAppear和viewDidAppear之間
使用說明:
只能在繼承了UIView的子類中通過重寫drawRect方法來繪制圖形雪隧; 如果需要繪制圖形的子類直接繼承自UIView,則子類的drawRect方法中不需要調(diào)用父類方法[super drawRect:rect]员舵;如果子類繼承自其他繼承UIView的View類脑沿,則drawRect方法中需要調(diào)用父類方法[super drawRect:rect];
補(bǔ)充:
-setNeedsDisplay方法:標(biāo)記為需要重繪马僻,異步掉用drawRect
-setNeedsDisplayInRect:(CGRect)invalidRect方法:標(biāo)記為需要局部重繪
比較:
layoutSubviews對(duì)subviews重新布局庄拇;drawRect是對(duì)receiver的重繪,能獲得context巫玻;
layoutSubviews方法調(diào)用先于drawRect丛忆;
setNeedsLayout在receiver標(biāo)上一個(gè)需要被重新布局的標(biāo)記祠汇,在系統(tǒng)runloop的下一個(gè)周期自動(dòng)調(diào)用layoutSubviews;layoutIfNeeded方法如其名熄诡,UIKit會(huì)判斷該receiver是否需要layout.
layoutIfNeeded遍歷的不是superview鏈可很,應(yīng)該是subviews鏈
setNeedDisplay在receiver標(biāo)上一個(gè)需要被重新繪圖的標(biāo)記,在下一個(gè)draw周期自動(dòng)重繪凰浮,iphone device的刷新頻率是60hz我抠,也就是1/60秒后重繪。
3.sizeToFit: resize當(dāng)前view,使得它找到最適合自己的大小.通常是通過view內(nèi)容來確定它自己的大小.不要重寫這個(gè)方法.
sizeToFit會(huì)計(jì)算出最優(yōu)的 size 而且會(huì)改變自己的size
sizeThatFits: 會(huì)計(jì)算出最優(yōu)的 size 但是不會(huì)改變 自己的size
使用這兩個(gè)方法必須先給label賦值袜茧。
常用場(chǎng)景
UILabel中,先設(shè)置label view的width,然后使用sizeToFit,會(huì)根據(jù)內(nèi)部文字多少,自適應(yīng)返回當(dāng)前l(fā)abel的size,其中height就是系統(tǒng)自動(dòng)計(jì)算的.(ps:這里也可以用NSString的boundingRect方法計(jì)算文字寬高,然后設(shè)置給label)
UIImageView, 如果該imageView中有圖片,調(diào)用sizeToFit,返回的size就是內(nèi)部圖片的size
UISwitch, 這個(gè)控件的默認(rèn)size是固定的,調(diào)用以后返回默認(rèn)的size.(ps:如果需要改變大小,使用transform屬性)
navigationItem, 如果設(shè)置它使用customView時(shí)候,最好先調(diào)用sizeToFit
補(bǔ)充:UILabel中有一個(gè)關(guān)鍵屬性adjustsFontSizeToFitWidth,可以通過label的width反向自適應(yīng)設(shè)置字體的font.注意這個(gè)屬性需要配合baselineAdjustment=UIBaselineAdjustmentAlignCenters一起使用.