前言
筆者在做公司項目(mini)的時候被這個很簡單的問題困擾了很久型宙,出現(xiàn)的bug是Label的父控件總是超出了范圍仓洼,特別是在重新設(shè)置字體的時候芜果,這個問題很明顯蔽氨,之前還以為是系統(tǒng)的問題10.3暮刃,后面用來自己的手機(jī)系統(tǒng)(9.3)也總是會有問題跨算,不能夠精確的計算文字的高度導(dǎo)致scrollview的contentSize計算有誤!
解決問題
我們都知道在重新布局子控件的時候要調(diào)用- (void)layoutSubviews{ [super layoutSubviews];}
關(guān)鍵是怎么調(diào)用椭懊,筆者出現(xiàn)了一個重大的筆誤我想當(dāng)然的調(diào)用[self setNeedsLayout]
然而效果并沒有什么用诸蚕,它雖然能布局子控件,但并不能及時刷新,于是我又通過調(diào)用[self LayoutIfNeed]
完美的解決了這個bug!
總價一些layout方法
- layoutSubviews
- layoutIfNeeded
- setNeedsLayout
- setNeedsDisplay
- drawRect
- sizeThatFits
- sizeToFit
- boundingRectWithSize
這些是常用的背犯,肯定還有其他很多歡迎補(bǔ)充
layoutSubviews
這個方法坏瘩,默認(rèn)沒有做任何事情,需要子類進(jìn)行重寫 漠魏。 系統(tǒng)在很多時候會去調(diào)用這個方法:
- 初始化不會觸發(fā)layoutSubviews倔矾,但是如果設(shè)置了不為 CGRectZero的frame的時候就會觸發(fā)。
- addSubview會觸發(fā)layoutSubviews
- 設(shè)置view的Frame會觸發(fā)layoutSubviews柱锹,當(dāng)然前提是frame的值設(shè)置前后發(fā)生了變化
- 滾動一個UIScrollView會觸發(fā)layoutSubviews
- 旋轉(zhuǎn)Screen會觸發(fā)父UIView上的layoutSubviews事件
- 改變一個UIView大小的時候也會觸發(fā)父UIView上的layoutSubviews事件
在蘋果的官方文檔中強(qiáng)調(diào): You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.layoutSubviews, 當(dāng)我們在某個類的內(nèi)部調(diào)整子視圖位置時哪自,需要調(diào)用。反過來的意思就是說:如果你想要在外部設(shè)置subviews的位置奕纫,就不要重寫提陶。
setNeedsLayout
標(biāo)記為需要重新布局,不立即刷新匹层,(那有什么用)但layoutSubviews一定會被調(diào)用
配合layoutIfNeeded立即更新
layoutIfNeeded
如果隙笆,有需要刷新的標(biāo)記,立即調(diào)用layoutSubviews進(jìn)行布局
drawRect
這個方法是用來重繪的(平時用的少升筏,就不過多總結(jié)撑柔,網(wǎng)上一大把)配合setNeedsDisplay
size to fit
這個方法可以手動計算文字的寬高度
- sizeToFit會自動調(diào)用sizeThatFits方法;
- sizeToFit不應(yīng)該在子類中被重寫您访,應(yīng)該重寫sizeThatFits
- sizeThatFits傳入的參數(shù)是receiver當(dāng)前的size铅忿,返回一個適合的size
- sizeToFit可以被手動直接調(diào)用sizeToFit和sizeThatFits方法都沒有遞歸,對subviews也不負(fù)責(zé)灵汪,只負(fù)責(zé)自己
boundingRectWithSize
我發(fā)現(xiàn)用boundingRectWithSize計算高度的時候會計算失誤檀训,就是短一些,但是不知道短多少享言,后來發(fā)現(xiàn)是短了字體高度的一半峻凫,加上這個高度才是正確的高度±缆叮可能是label必須留出上下的這個高度才可以吧荧琼。(摘抄網(wǎng)上的bug,筆者目前暫未發(fā)現(xiàn)差牛,平時用的都挺好的)