我报名参与金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击检查活动详情”

前语

在过去iOS页面布局较为传统,大多数人运用Frame或许AutoLayout来布局,在iOS9以后,引入了UIStackViewUIStackView是用于线性布局的控件,能够主动管理子视图布局,主动填充。它学习了前端的布局算法Flexbox,能够简便地完成各种页面布局。

UIStackView尽管已经不是新控件了,但仍是有许多同学并没有运用起来。有时需求修正他人的代码看到乱糟糟的布局代码就有许多槽点。所以这也是写这篇文章的目的地点,真的引荐咱们运用StackView,能够让你事半功倍,省下来的时间摸鱼不香嘛。

回归正题,不管是运用Frame或许AutoLayout来布局,咱们都需求对一切的控件的方位、巨细进行设置,Frame需求指定方位布局,AutoLayout需求指定束缚布局;而UIStackView布局方法凸显它的优势在于不需求设置摆放视图(即子视图)的方位,巨细(不是必须的),而是经过本身的摆放、散布方法主动完结布局。比照起来,运用UIStackView更高效,咱们能够经过嵌套UIStackView快速完结林林总总的布局。

UIStackView布局思维

UIStackView的初衷便是为了简化的界面布局,适用于列或行中布局视图集合。

StackView运用主动布局(AutoLayout)来定位和设置其摆放视图的巨细。StackView将榜首个和最终一个摆放的视图与其沿仓库轴的边际对齐。在水平仓库中,这意味着榜首个摆放视图的前缘被固定在StackView的前缘上,而最终一个摆放视图的后缘被固定在StackView的后缘上;在笔直仓库中,顶部和底部边际别离固定在仓库的顶部和底部边际上。

StackView会依据本身的布局规矩进行填充摆放视图。

使用UIStackView来简化iOS的界面布局

distribution:

distribution 即摆放方法:

  • fill依据抗拉伸、压缩优先级填充(默认拉伸榜首个摆放视图)
  • fillEqually在摆放方向上的填充巨细相同(即横向布局宽度相同,纵向布局高度相同)
  • fillProportionally依据摆放视图的巨细按份额填充
  • equalSpacing均匀地填充视图之间的距离
  • equalCentering依据摆放视图中心点之间的相同间隔填充

alignment:

alignment即对齐方法:(笔直于摆放方向)

  • fill填充摆放视图到StackView的可用空间
  • topStackView的顶部摆放(与之相似的是leading
  • bottomStackView的尾部摆放(与之相似的是trailing
  • centerStackView的中心摆放
  • firstBaseline以榜首个基准线摆放
  • lastBaseline以最终一个的基准线摆放

如需设置摆放视图之间的距离能够经过设置space特点,若是摆放视图之间的距离不同,能够运用方法指定某个摆放视图的距离(此方法iOS11以上运用),或许运用一个无用的view插入在视图之间替代空隙,此view仅作为距离运用(运用xibStoryboard会经常运用此类方法,能够参照)。

当你真的了解UIStackView的这些布局思维之后,你就会知道它能帮你处理许多繁琐的布局。(如一个多变的底部操作栏、一行巨细各异的控件等等)

从上面的布局思维中,不难看出,其实咱们仅需求确定StackView的摆放方向,以及摆放方法、对其方法,就能大体上对整个摆放视图开始的布局,而后在依据不同的视图进行巨细上的调整以及距离的调整即可。

运用UIStackView来主动布局子视图,你只需求每个子视图重视本身的巨细即可。

以此类操作栏为例,举个栗子:

使用UIStackView来简化iOS的界面布局
使用UIStackView来简化iOS的界面布局

先说说咱们常用的布局方法,或许仍是会有一部分人会挑选Frame布局,或许AutoLayout布局。

但此类UI在规划之初,一般会有许多状况、特征,每一种状况下,控件都会变化。

那么Frame布局在这种布局容易变化的情况下,就显得有十分的繁琐,布局代码十分的多,并且状况许多的时分不好保护。 同样AutoLayout也是如此,需求写许多的更新布局束缚。

这个时分,借用UIStackView的思维,咱们能够很简单的完成这个布局。每个控件只重视本身巨细,不会对其他的空间发生依靠联系,在需求时显示出来,不需求时躲藏起来。

咱们先以文本输入入口“说点什么”小试牛刀。

使用UIStackView来简化iOS的界面布局

下面便是用StackView布局的作用。

使用UIStackView来简化iOS的界面布局

这儿我是运用的xib结合StackView。如果咱们平时运用的代码布局,也能够运用代码结合StackView布局,这样也会削减许多代码量,能够自行脑补。

UIStackView用法

初始化

与其他控件相同的初始化方法;

- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

当然也能够挑选专属的初始化方法;

- (instancetype)initWithArrangedSubviews:(NSArray<__kindof UIView *> *)views;

添加、删去子视图

- (void)addArrangedSubview:(UIView *)view;
- (void)removeArrangedSubview:(UIView *)view;

摆放方向

@property(nonatomic) UILayoutConstraintAxis axis;
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
  UILayoutConstraintAxisHorizontal = 0, // 水平方向
  UILayoutConstraintAxisVertical = 1    // 笔直方向
};

布局方法

@property(nonatomic) UIStackViewDistribution distribution;
typedef NS_ENUM(NSInteger, UIStackViewDistribution) {
  UIStackViewDistributionFill = 0, //子视图填充满指定方向,优先拉伸榜首个控件
  UIStackViewDistributionFillEqually, //每个子视图填充巨细持平,
  UIStackViewDistributionFillProportionally, //依据每个子视图里面内容的尺寸来进行填充操作
  UIStackViewDistributionEqualSpacing, //每个子视图之间的距离持平
  UIStackViewDistributionEqualCentering, //每个子视图中心直接的距离持平
} API_AVAILABLE(ios(9.0));

对齐方法

@property(nonatomic) UIStackViewAlignment alignment;
typedef NS_ENUM(NSInteger, UIStackViewAlignment) { 
    UIStackViewAlignmentFill, //水平:subView的上下和StackView的上下边距 持平   笔直: subView的左右边距和 StackView的一切持平 
    UIStackViewAlignmentLeading,//笔直有用 :左对齐
    UIStackViewAlignmentTop = UIStackViewAlignmentLeading, // 水平有用 上对齐
    UIStackViewAlignmentFirstBaseline,//水平有用,榜首行基准线对齐。
    UIStackViewAlignmentCenter, //中心基准线对齐 1.水平 高度中点对齐 2.笔直:宽度中点对齐
    UIStackViewAlignmentTrailing,  //笔直有用,右边界对齐。
    UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing,// 水平有用 ,下边界对齐。
    UIStackViewAlignmentLastBaseline,//水平有用,最终一行基准线对齐。
} API_AVAILABLE(9_0);

距离

@property(nonatomic) NSInteger space; //摆放视图相邻边际之间的距离。