————————————————UIStackView的應用————————————————
一:先講下優勢:
對於排布列表式控件的布局需求,用UIStackView控件,開發中為我們省去了繁瑣的代碼,便利了布局
布局圖片演示:
垂直布局樣式 水平布局樣式
二:在應用之前,先介紹幾個屬性
- —Axis--
是設置布局的方向,有水平和垂直兩種方式,一個StackView只能選擇一種布局模式。
- —Alignment--
是選擇其管理視圖的對齊模式,我們這里選擇充滿。
- -Distribution-
是設置其管理視圖的排列方式,我們選擇等寬充滿。
- —Spacing--
是設置視圖之間的間距,默認設置為10.
三:分析注意
之后有一點需要注意,stackView用於布局其內部管理的視圖,對於它本身,我們還需要添加一些約束,將它約束在屏幕的中間。
我們向其中拖入任意數量的view,設置不同的顏色,就實現了我們想要的效果,並且可以隨意動態刪除和添加其中的view數量,不需要改變約束。
四:UIStackView的創建
- --動態添加視圖--
UIView * newView = [[UIView alloc]init];
[stackView addArrangedSubview:newView];
addArrangedSubview和addSubview有很大的區別,使用前者是將試圖添加進StackView的布局管理,
后者只是簡單的加在試圖的層級上,並不接受StackView 的布局管理
- --動畫效果--
因為StackView繼承於UIView,因此在布局改變的時候,我們可以使用UIView層的動畫,如下:
//注意:在添加view的時候會有動畫效果,移除的時候沒有
[stackView addArrangedSubview:newView];
[UIView animateWithDuration:1 animations:^{
[stackView layoutIfNeeded];
}];
- --方法管理---
//初始化方法,通過數組傳入被管理的視圖
- (instancetype)initWithArrangedSubviews:(NSArray<__kindof UIView *> *)views;
//獲取被管理的所有視圖
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *arrangedSubviews;
//添加一個視圖進行管理
- (void)addArrangedSubview:(UIView *)view;
//移除一個被管理的視圖
- (void)removeArrangedSubview:(UIView *)view;
//在指定位置插入一個被管理的視圖
- (void)insertArrangedSubview:(UIView *)view atIndex:(NSUInteger)stackIndex;
- ---與StackView布局設置相關:---
1.布局模式:
@property(nonatomic) UILayoutConstraintAxis axis;
注意:上面這個屬性用於設置布局的模型,枚舉如下:
//stackView只有兩種布局模式 水平和豎直
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal = 0,//水平布局
UILayoutConstraintAxisVertical = 1 //豎直布局
};
2.對齊模式:
@property(nonatomic) UIStackViewAlignment alignment;
注意:這個屬性用於設置控件的對其模式,枚舉如下:
typedef NS_ENUM(NSInteger, UIStackViewAlignment) {
UIStackViewAlignmentFill, //水平布局時為高度充滿,豎直布局時為寬度充滿
UIStackViewAlignmentLeading, //前邊對其
UIStackViewAlignmentTop = UIStackViewAlignmentLeading, //頂部對其
UIStackViewAlignmentFirstBaseline, //第一個控件文字的基線對其 水平布局有效
UIStackViewAlignmentCenter, //中心對其
UIStackViewAlignmentTrailing, //后邊對其
UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing, //底部對其
UIStackViewAlignmentLastBaseline, //基線對其,水平布局有效
} NS_ENUM_AVAILABLE_IOS(9_0);
3.排列方式
@property(nonatomic) UIStackViewDistribution distribution;
注意:排列方式的枚舉如下:
typedef NS_ENUM(NSInteger, UIStackViewDistribution) {
UIStackViewDistributionFill = 0, //充滿,當只有一個控件時可以使用
UIStackViewDistributionFillEqually, //平分充滿,每個控件占據相同尺寸排列充滿
UIStackViewDistributionFillProportionally, //會優先按照約束的尺寸進行排列,如果沒有充滿,會拉伸最后一個排列的控件充滿
UIStackViewDistributionEqualSpacing, //等間距排列
UIStackViewDistributionEqualCentering, //中心距離相等
} NS_ENUM_AVAILABLE_IOS(9_0);
4.其他
//設置最小間距
@property(nonatomic) CGFloat spacing;
//設置布局時是否參照基線
@property(nonatomic,getter=isBaselineRelativeArrangement) BOOL baselineRelativeArrangement;
//設置布局時是否以控件的LayoutMargins為標准,默認為NO,是以控件的bounds為標准
@property(nonatomic,getter=isLayoutMarginsRelativeArrangement) BOOL layoutMarginsRelativeArrangement;
五:實戰案例代碼(包括: * 獨立處理指定子控件的某一布局屬性)
-(void)setupUIUIStackView{
NSMutableArray <UIImageView *>*rray = [NSMutableArray array];
for(int i = 0;i < 4;i++){
UIImage *image = [UIImage imageNamed:@"ic_sport_gps_map_mixmode_selected"];
UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
//布局尺寸優先級最高
if (i == 1) {
//-------------注意:這里是獨立處理指定子控件的高度布局屬性--------------
[imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@65);
}];
}
[rray addObject:imageView];
}
UIStackView *stackView = [[UIStackView alloc]initWithArrangedSubviews:rray];
[self.view addSubview:stackView];
//父類布局
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.height.equalTo(@80);
make.width.equalTo(@300);
}];
//子類布局
[stackView setAxis:UILayoutConstraintAxisHorizontal]; //排列類型
[stackView setDistribution:UIStackViewDistributionFillEqually]; //子控件大小一樣
[stackView setSpacing:20]; //子控件間距
[stackView setAlignment:UIStackViewAlignmentBottom]; //底部對其
//添加動畫
[UIView animateWithDuration:1.3 animations:^{
[stackView layoutIfNeeded];
}];
}
效果圖:注(創建的時候會帶動畫效果)
結束語:到這里基本開發的用法我就講完了。
由於發現項目中很少有人用這個簡便的控件,所以今天有空出了這章講解,各位iOS的開發熱愛者們可以先用起來了!
如用糾正,歡迎交流!