最近從同事那裏瞭解到UIStackView這個API,以前使用到的自動佈局有代碼自動佈局(Masonary)和拖 constraint 這兩種。UIStackView和這兩種相比能夠減小重複繁瑣的工做,使自動佈局變得方便快捷。github
UIStackView是蘋果推出的一套能夠自動佈局的API,適配iOS9.0以後,iOS8.0以前的不支持,UIStackView是一個容器,UIStackView繼承自UIView,可是它自己不能自我渲染,好比爲他設置 backgroundColor 是無效的,因此它要和 UIView 相輔相成的進行工做。它可以幫助 UIView 來處理 子視圖 的位置和大小等佈局問題。他的定位是介於 手寫約束 和 UITableView/UICollectionView 之間的工具。數組
UIStackView通常用於實現水平平鋪一行或者垂直平鋪一行的視圖組合。bash
用一個簡圖表示一下UIStackView和父視圖以及子視圖之間的繼承關係工具
代碼初始化一個stackView並添加到父視圖上佈局
- (void)initStackView{
self.stackView = [[UIStackView alloc] init];
self.stackView.axis = UILayoutConstraintAxisHorizontal;
self.stackView.distribution = UIStackViewDistributionFill;
self.stackView.spacing = 10;
self.stackView.alignment = UIStackViewAlignmentFill;
self.stackView.frame = CGRectMake(0, 100, ScreenWidth, 200);
[self.view addSubview:self.stackView];
}
複製代碼
決定了 stack 的朝向,只有垂直或水平;ui
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal = 0,//水平佈局方向
UILayoutConstraintAxisVertical = 1//垂直佈局方向
};
複製代碼
描述了其管理的子視圖在沿着其軸向(axis)上的佈局關係;spa
typedef NS_ENUM(NSInteger, UIStackViewDistribution) {
UIStackViewDistributionFill = 0,
UIStackViewDistributionFillEqually,
UIStackViewDistributionFillProportionally,
UIStackViewDistributionEqualSpacing,
UIStackViewDistributionEqualCentering,
} NS_ENUM_AVAILABLE_IOS(9_0);
複製代碼
它就是將 arrangedSubviews 填充滿整個 StackView ,若是設置了spacing,那麼這些 arrangedSubviews 之間的間距就是spacing。若是減去全部的spacing,全部的 arrangedSubview 的固有尺寸( intrinsicContentSize )不能填滿或者超出 StackView 的尺寸,那就會按照 Hugging 或者 CompressionResistance 的優先級來拉伸或壓縮一些 arrangedSubview 。若是出現優先級相同的狀況,就按排列順序來拉伸或壓縮。3d
這種就是 StackView 的尺寸減去全部的spacing以後均分給 arrangedSubviews ,每一個 arrangedSubview 的尺寸是相同的。code
這個和FillEqually差很少,只是這個不是將尺寸均分給 arrangedSubviews ,而是根據 arrangedSubviews 的 intrinsicContentSize 按比例分配。
這種是使 arrangedSubview 之間的spacing相等,可是這個spacing是有可能大於 StackView 所設置的spacing,可是絕對不會小於。這個類型的佈局能夠這樣理解,先按全部的 arrangedSubview 的 intrinsicContentSize 佈局,而後餘下的空間均分爲spacing,若是大約 StackView 設置的spacing那這樣就OK了,若是小於就按照 StackView 設置的spacing,而後按照 CompressionResistance 的優先級來壓縮一個 arrangedSubview 。
這種是使 arrangedSubview 的中心點之間的距離相等,這樣沒兩個 arrangedSubview 之間的spacing就有可能不是相等的,可是這個spacing仍然是大於等於 StackView 設置的spacing的,不會是小於。這個類型佈局仍然是若是 StackView 有多餘的空間會均分給 arrangedSubviews 之間的spacing,若是空間不夠那就按照 CompressionResistance 的優先級壓縮 arrangedSubview 。
決定了其管理的視圖在垂直於其軸向上的佈局;
typedef NS_ENUM(NSInteger, UIStackViewAlignment) {
UIStackViewAlignmentFill,//子視圖填充StackView
UIStackViewAlignmentLeading,//子視圖左對齊(axis爲垂直方向而言)
UIStackViewAlignmentTop = UIStackViewAlignmentLeading,//子視圖頂部對齊(axis爲水平方向而言)
UIStackViewAlignmentFirstBaseline, // 按照第一個子視圖的文字的第一行對齊,同時保證高度最大的子視圖底部對齊(只在axis爲水平方向有效)
UIStackViewAlignmentCenter,//子視圖居中對齊
UIStackViewAlignmentTrailing,//子視圖右對齊(axis爲垂直方向而言)
UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing,//子視圖底部對齊(axis爲水平方向而言)
UIStackViewAlignmentLastBaseline, // 按照最後一個子視圖的文字的最後一行對齊,同時保證高度最大的子視圖頂部對齊(只在axis爲水平方向有效)
} NS_ENUM_AVAILABLE_IOS(9_0);
複製代碼
默認方式, 若是子控件水平佈局, 則指子控件的垂直方向填充滿stackView. 反之亦然。
若是子控件豎直佈局, 則指子控件左邊對齊stackView左邊. 反之亦然。
按照第一個子視圖的文字的第一行對齊,同時保證高度最大的子視圖底部對齊(只在axis爲水平方向有效)
子視圖居中對齊。
子視圖右對齊(axis爲垂直方向而言)。
axis爲水平時UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing。
按照最後一個子視圖的文字的最後一行對齊,同時保證高度最大的子視圖頂部對齊(只在axis爲水平方向有效)
設置子視圖之間的間距,是子視圖之間的最小間距,之因此說是最小間距,由於stackView會根據必定的規則對內部空間佈局,有的時候不能知足全部要求,好比stackView 自己寬度100,內部兩個控件,寬度都爲100,100+100+10就超過了自己寬度, 這時會壓縮其中一個子控件的寬度來知足最小間距。
決定了其視圖間的垂直間隙是否根據基線測量獲得。
決定了 stackView 平鋪其管理的子視圖時是否要參照它的佈局邊距,若是是YES則經過 layout margins 佈局,爲NO則經過 bounds佈局。
-initWithArrangedSubviews: (New in iOS 9.0):初始化子視圖數組
-addArrangedSubview: (New in iOS 9.0): 添加子視圖
3.2.2 -arrangedSubviews Property (New in iOS 9.0): UIStackView使用arrangedSubviews數組來管理子視圖。
3.2.3 -insertArrangedSubview:atIndex: (New in iOS 9.0):根據下標插入視圖
-removeArrangedSubview: (New in iOS 9.0):移除子視圖
注意:addArrangedSubview和insertArrangedSubview,會把子視圖添加到arrangedSubviews數組的同時也添加到StackView上,可是removeArrangedSubview,只會把子視圖從arrangedSubviews數組中移除,不會從subviews中移除,若是須要可調用removeFromSuperview。
附上gitHub demo
UIStackView能夠經過代碼或者xib實現,平時工做中一邊使用代碼實現,代碼更方便後期項目的功能修改,更便於維護。學會它的使用能方便咱們快速開發新功能。但願能和你們探討更多關於UIStackView的知識。