一匾二、了解 instric content size
instric content size
表示一個(gè)view
的固有的大小,對于UILabel
,UIImageView
,UIButton
這些元素來說,在沒有顯式設(shè)置大小的時(shí)候樊卓,它總是有一個(gè)內(nèi)容撐開的大小
它們是通過方法-(CGSize)instricContentSize
來返回的豪硅,UIView
返回的是一個(gè)zeroSize
, 也是大小為0x0, 不可見其弊。
我們可以繼承UIView
, 添加一個(gè)可以設(shè)置的固有大小值霍骄,來幫助我們更好的完成布局群嗤。
#import "ESView.h"
@implementation ESView
-(CGSize)intrinsicContentSize{
CGSize size = [super intrinsicContentSize];
if(self.es_intrinsicWidth && self.es_intrinsicHeight){
return CGSizeMake(self.es_intrinsicWidth, self.es_intrinsicHeight);
}
return size;
}
@end
二、UIStackView
的特性
UIStackView
是一個(gè)容器決定內(nèi)容排版的布局模式氏淑,容器大小的變化勃蜘,會影響子項(xiàng)的排版。
類似前端體系中的flexbox
的簡化版夸政。
-
UIStackView
是一個(gè)虛擬容器元旬,它的layer
不被繪制榴徐,設(shè)置背景守问、邊框、陰影這些外觀是無效的坑资。 - 官方中文文檔
- 如果我們使用約束耗帕,不定義棧視圖的大小,只定義位置袱贮,這個(gè)時(shí)候仿便,棧視圖不會再改變管理內(nèi)容的大小,相反攒巍,它會自動計(jì)算出自己需要的大小嗽仪,也就是變成了不換行的流式布局。
也就是它會生成一個(gè)固有大小柒莉,進(jìn)行內(nèi)容自適應(yīng)排版闻坚。
三、基本用法
1兢孝、創(chuàng)建一個(gè) UIStackView
窿凤。
CGSize size = self.view.bounds.size;
UIStackView *sView = [[UIStackView alloc] initWithFrame:CGRectMake(0, 64, size.width, size.height*0.5)];
[self.view addSubview:sView];
可以為它指定固定的 frame
, 也可以添加約束。
2跨蟹、設(shè)置軸向雳殊。
sView.axis = UILayoutConstraintAxisVertical;
//sView.axis = UILayoutConstraintAxisHorizontal;
軸向決定了子項(xiàng)的排列方向,分為水平與垂直兩種窗轩。
3夯秃、設(shè)置最小間距。
sView.spacing = 2;
默認(rèn)間距是0, 最小間距的意思就是在子項(xiàng)大小超過容器時(shí),也必須保持的間距仓洼,真實(shí)間距有可能比它大箫措。
4、設(shè)置副軸上子項(xiàng)的對齊方式衬潦。
sView.alignment = UIStackViewAlignmentTop;
副軸指的是當(dāng)前axis的正交軸斤蔓,對齊方式有上、中镀岛、下弦牡、兩端4類。
-
UIStackViewAlignmentFill
在副軸方向兩端對齊漂羊,也就是拉伸填滿驾锰。 -
UIStackViewAlignmentTop
和UIStackViewAlignmentLeading
等效,也就是向開始端對齊走越。 -
UIStackViewAlignmentBottom
和UIStackViewAlignmentTrailing
類似椭豫,也就是向結(jié)束端對齊。 -
UIStackViewAlignmentCenter
居中旨指。 -
UIStackViewAlignmentFirstBaseline
,UIStackViewAlignmentLastBaseline
對齊第一行或者最后一行文本的基線赏酥。
5、設(shè)置內(nèi)容軸向的寬度或者高度模式谆构。
sView.distribution = UIStackViewDistributionEqualCentering;
它有5種模式:
-
UIStackViewDistributionFill
裸扶,默認(rèn)的全軸填滿模式,在保證最小間距的前提下搬素,對子項(xiàng)進(jìn)行壓縮或者拉伸呵晨,調(diào)節(jié)時(shí)考慮子項(xiàng)的抗拉伸或者抗壓縮級別,如果有的話, 如果沒有先從第一個(gè)開始拉伸或者壓縮熬尺。
UIView
默認(rèn)是可以設(shè)置拉伸或者壓縮優(yōu)先級的, 優(yōu)先級越高的摸屠,越先做伸縮。
[view setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
拉伸是無限的粱哼,所以一般來說季二,只會拉伸一個(gè)子元素,而壓縮是有限的皂吮,第一個(gè)壓縮完了不夠戒傻,就會壓縮第二個(gè)。
-
UIStackViewDistributionFillEqually
, 忽略固有大小蜂筹,全部強(qiáng)制均分填滿需纳。 -
UIStackViewDistributionFillProportionally
, 軸向填滿,等比例調(diào)節(jié)艺挪。 -
UIStackViewDistributionEqualSpacing
, 等距模式不翩,在大小有剩余的時(shí)候兵扬,分配到間距上,如果不足口蝠,進(jìn)行壓縮器钟。 -
UIStackViewDistributionEqualCentering
, 中心點(diǎn)等距模式,子項(xiàng)的中心點(diǎn)距離相同妙蔗,間距可能各有不同傲霸,固有尺寸越小,邊距越大眉反,其實(shí)就是先打均分中心點(diǎn)昙啄,再繪制。
所有模式都是讓子項(xiàng)均勻排版寸五,對于空間剩余的情況下梳凛,分配策略不同。
注意它們軸向兩端都是貼邊的梳杏, 也就是說韧拒,它的軸向?qū)R方式就是兩端對齊 just
。
可以設(shè)置margin來添加外邊距
sView.layoutMarginsRelativeArrangement = YES;
sView.layoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
如果只有一個(gè)子項(xiàng)的時(shí)候十性,總是被拉伸了叛溢。
適應(yīng)場景
適用于單行或者單列,已知容器大小的前提下排版烁试, 沒有
flexbox
那樣可以自動換行雇初。
至少要保證軸向大小是可知的,副軸方向可以取決于內(nèi)容大小减响。
- 因?yàn)槔斓膬?yōu)先級特性,我們可以設(shè)計(jì)類似css中的雙飛翼郭怪、一邊固定支示,一邊自適應(yīng)的排版。