在ios的開發中,遇到UIView的排版問題,自然少不了layoutSubviews 這個函數與autoresizingMask這個屬性。
在superview的autoresizesSubviews爲Yes的時候,會根據subview的autoresizingMask類型進行自動排版,autoresizingMask可選的屬性有
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
因爲橫向和縱向的變換方式是一樣的,所以就以iPhone中更常用的縱向變換爲例了:
UIViewAutoresizingNone:superview變換時,自己不作變換。
UIViewAutoresizingFlexibleHeight:上邊距不變,和superview在高度上變換同等高度。 比如,superview加高100,則自己也加高100。
UIViewAutoresizingFlexibleTopMargin:高度不變。上邊距彈性可變,下邊距保持不變。
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight: 這個組合的變換比較繞: 首先,下邊距是不變的,但高和上邊距會變,變換的計算如下, 比如superview的高度,由100加高的200。自己的下邊距是50, 則去掉不變的下邊距後,superview的變化比例是:(100-50)/(200-50) = 50/150 = 1/3。 則自己的上邊距和高都變爲越來的3倍。
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin : 這個變換的計算就比較簡單了,救是自己的上邊距,高,下邊距都和superview同比變換。 比如superview的高由100變爲200。則自己的上邊距,高,下邊距也都變爲原來的2倍。
但對layoutSubviews這個函數何時會被調用卻一直不是很清楚,只是知道設置frame的時候,會異步的調用,這裏的文章中總結出了幾點場景:
- init does not cause layoutSubviews to be called (duh)
- addSubview causes layoutSubviews to be called on the view being added, the view it’s being added to (target view), and all the subviews of the target view
- setFrame intelligently calls layoutSubviews on the view having it’s frame set only if the size parameter of the frame is different
- scrolling a UIScrollView causes layoutSubviews to be called on the scrollView, and it’s superview
- rotating a device only calls layoutSubview on the parent view (the responding viewControllers primary view)
- removeFromSuperview – layoutSubviews is called on superview only (not show in table)
針對setFrame這一條,曾經以爲在layoutSubviews中通過self.frame重新設置一個不同的frme,會再次調用layoutSubviews從而導致死循環,經過實驗發現並未產生,還不知道具體的原因。
1.在如果subview設置了autoresizingMask,而supview中的重寫了layoutsubviews,並且其中對subview進行了指定排版,那麼subview的autoresizingMask將不會起作用的
2.xib裏面的組件寬度和高度不能爲0,否則xib裏面的組件會重置爲(0 0,0 0)