iOS-setNeedsLayout等布局方法

來源:互聯網
上載者:User

iOS-setNeedsLayout等布局方法

列舉下iOS layout的相關方法:

layoutSubviews
layoutIfNeeded
setNeedsLayout
setNeedsDisplay
drawRect
sizeThatFits
sizeToFit
大概常用的上面幾個 , 具體的應該還有別的。

layoutSubviews
這個方法,預設沒有做任何事情,需要子類進行重寫 。 系統在很多時候會去調用這個方法:

1.初始化不會觸發layoutSubviews,但是如果設定了不為CGRectZero的frame的時候就會觸發。
2.addSubview會觸發layoutSubviews
3.設定view的Frame會觸發layoutSubviews,當然前提是frame的值設定前後發生了變化
4.滾動一個UIScrollView會觸發layoutSubviews
5.旋轉Screen會觸發父UIView上的layoutSubviews事件
6.改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件

在蘋果的官方文檔中強調: You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.layoutSubviews, 當我們在某個類的內部調整子視圖位置時,需要調用。反過來的意思就是說:如果你想要在外部設定subviews的位置,就不要重寫。
setNeedsLayout
標記為需要重新布局,不立即重新整理,但layoutSubviews一定會被調用
配合layoutIfNeeded立即更新

layoutIfNeeded
如果,有需要重新整理的標記,立即調用layoutSubviews進行布局

這個動畫中有用到 舉個栗子 。

, 上面有個label ,中間有個按鈕 , label已經被自動布局到左上方 。 然後我們那個left的constraint

@IBOutlet weak var leftContrain:NSLayoutConstraint!
在viewDidLoad中聲明好,然後在Main.storyboard中進行連線。點擊按鈕的時候 ,我們把左邊的距離改成100 。

在按鈕的點擊事件裡加上這句。

leftContrain.constant = 100
然後我們想要一個動畫的效果。
如果這麼做

UIView.animateWithDuration(0.8, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: UIViewAnimationOptions.AllowAnimatedContent, animations: {
self.leftContrain.constant = 100
}, completion: nil)
你會發現然並卵 。其實這句話self.leftContrain.constant = 100隻是執行了setNeedsLayout 標記了需要重新布局,但是沒有立即執行。所以我們需要在動畫中調用這個方法layoutIfNeeded
所以代碼應該這麼寫

leftContrain.constant = 100
UIView.animateWithDuration(0.8, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: UIViewAnimationOptions.AllowAnimatedContent, animations: {
self.view.layoutIfNeeded() //立即實現布局
}, completion: nil)
所以上面不管寫多少約束的改變,只需要在動畫裡動用 一次self.view.layoutIfNeeded() ,所有的都會已動畫的方式 。如果一些變化不想動畫 。在動畫前執行self.view.layoutIfNeeded()

drawRect
這個方法是用來重繪的。

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即時重新整理螢幕

sizeToFit
sizeToFit會自動調用sizeThatFits方法;
sizeToFit不應該在子類中被重寫,應該重寫sizeThatFits
sizeThatFits傳入的參數是receiver當前的size,返回一個適合的size
sizeToFit可以被手動直接調用sizeToFit和sizeThatFits方法都沒有遞迴,對subviews也不負責,只負責自己

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.