UIStackView學(xué)習(xí)分享经瓷, 純代碼實(shí)現(xiàn)

最近看葉孤城的書爆哑,里面提到了UIStackView,說起這種布局舆吮,也是很早就知道了揭朝,但是一直沒有研究過,開發(fā)中也沒有使用過歪泳,周末上網(wǎng)翻看一下了大家的文章萝勤,發(fā)現(xiàn)大多都是Storyboard講解的露筒,實(shí)際上使用代碼或者Storyboard對于UIStackView區(qū)別不大呐伞,因?yàn)閁IStackView本身的屬性就很少,由于本人開發(fā)中從不使用Storyboard或者xib慎式, 本篇demo就用純代碼完成吧伶氢, 關(guān)鍵是網(wǎng)上的一些布局給的示例也不是特別清楚趟径,由于開發(fā)中也沒有實(shí)際用過,本文內(nèi)容僅限交流學(xué)習(xí)癣防, 大家交流指正蜗巧。

一,UIStackView是什么蕾盯?
在iOS9中蘋果在UIKit框架中引入了一個(gè)新的視圖類UIStackView幕屹。UIStackView 類提供了一個(gè)高效的接口用于平鋪一行或一列的視圖組合。Stack視圖管理著所有在它的 arrangedSubviews 屬性中的視圖的布局级遭。這些視圖根據(jù)它們在 arrangedSubviews 數(shù)組中的順序沿著 Stack 視圖的軸向排列望拖。
簡而言之,即UIStackView挫鸽,就是一個(gè)ContainerView说敏,可以沿橫向或縱向按照一定的規(guī)則布局內(nèi)部的子View。
為了避免太過無聊丢郊, 先放出demo中實(shí)現(xiàn)的一個(gè)效果盔沫, demo地址

效果

二,一個(gè)快速示例

下面用一個(gè)很簡單的示例快速演示一下枫匾,


示例1

想一下要布局上圖中的View架诞,如果用Frame,或者autolayout的過程干茉,都是比較復(fù)雜侈贷,masonry中有一種相對簡單的方式, 可以看這篇文章masonry-等間距布局等脂,以上方式都不演示了俏蛮, 沒什么可說的。

如果使用UIStackView上遥, 如下為實(shí)現(xiàn)代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    containerView = [[UIStackView alloc] initWithFrame:CGRectMake(0, 100, ScreenWidth, 200)];
    containerView.axis = UILayoutConstraintAxisHorizontal;
    containerView.distribution = UIStackViewDistributionFillEqually;
    containerView.spacing = 10;
    containerView.alignment = UIStackViewAlignmentFill;
    
    for (NSInteger i = 0; i < 4; i++) {
        UIView *view = [[UIView alloc] init];
        view.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
        [containerView addArrangedSubview:view];
    }
    
    [self.view addSubview:containerView];
}

以上就是所有代碼搏屑, 是不是看起來異常簡單, 前面說過了StackView其實(shí)就是一個(gè)容器View粉楚,可以管理內(nèi)部子控件的布局辣恋, 那么看一下代碼, init不用說了模软, for循環(huán)創(chuàng)建子控件不用說了(addArrangedSubview:view見下文)伟骨, addSubViews也不用說, 那么久只剩下了四行代碼燃异, 這四個(gè)也就是UIStackView全部四個(gè)屬性

[containerView addArrangedSubview:view]相關(guān)介紹:
UIStackView使用arrangedSubviews數(shù)組來管理子視圖携狭。
需要注意的是這個(gè)數(shù)組是一個(gè)readonly的屬性,我們需要調(diào)用方法對arrangedSubviews數(shù)組進(jìn)行操作回俐。
初始化數(shù)組:
- (instancetype)initWithArrangedSubviews:(NSArray<__kindof UIView *> *)views;
添加子視圖: 
- (void)addArrangedSubview:(UIView *)view;
移除子視圖:
- (void)removeArrangedSubview:(UIView *)view;
根據(jù)下標(biāo)插入視圖:
- (void)insertArrangedSubview:(UIView *)view atIndex:(NSUInteger)stackIndex;

注意: addArrangedSubview 和 insertArrangedSubview逛腿, 會(huì)把子控件加到arrangedSubviews數(shù)組的同時(shí)添加到StackView上稀并, 
      但是removeArrangedSubview, 只會(huì)把子控件從arrangedSubviews數(shù)組中移除单默,
      不會(huì)從subviews中移除碘举,如果需要可調(diào)用removeFromSuperview

三,具體講解StackView的屬性

stackView屬性示例圖

1搁廓, axis:子控件的布局方向引颈,水平或垂直, 這個(gè)不用過多解釋了
2境蜕, spacing:子控件之間的最小間距线欲,之所以說是最小間距,因?yàn)閟tackView會(huì)根據(jù)一定的規(guī)則對內(nèi)部空間布局汽摹,有的時(shí)候不能滿足所有要求李丰,比如stackView 本身寬度100,內(nèi)部兩個(gè)控件逼泣,寬度都為50趴泌,50+50+10就超過了本身寬度, 這時(shí)會(huì)壓縮其中一個(gè)子控件的寬度來滿足最小間距拉庶。
3嗜憔, distribution:子控件依據(jù)何種規(guī)則布局, 這個(gè)比較抽象氏仗, 看示例理解的快一點(diǎn)吉捶,以下示例均使用UILabel演示, 原因見插播

插播:先了解一下什么是Intrinsic Content Size(固有尺寸)皆尔,
因?yàn)閁IStackView對子控件的布局是建立在Autolayout基礎(chǔ)之上的呐舔,
會(huì)涉及到Intrinsic Content Size
想一下當(dāng)為一個(gè)Label創(chuàng)建約束時(shí),是不是經(jīng)常只指定上邊距和左邊距慷蠕,
相信原因大家都知道珊拼,label內(nèi)部的文字自會(huì)撐開寬高, 
這個(gè)根據(jù)內(nèi)容自己撐開的寬高就是Intrinsic Content Size流炕。
怎樣給一個(gè)UIView設(shè)置Intrinsic Content Size 或者改變label的Intrinsic Content Size澎现?
繼承然后重寫
- (CGSize)intrinsicContentSize
{
    CGSize originalSize = [super intrinsicContentSize];
    CGSize size = CGSizeMake(originalSize.width+20, originalSize.height+20);
    return size;
}

UIStackViewDistribution是個(gè)枚舉值每辟, 各個(gè)值如下剑辫, 配有示例圖, 看不懂就只能自求多福了:
UIStackViewDistributionFill :它就是將 arrangedSubviews 填充滿整個(gè) StackView 渠欺,如果設(shè)置了spacing妹蔽,那么這些 arrangedSubviews 之間的間距就是spacing。如果減去所有的spacing,所有的 arrangedSubview 的固有尺寸( intrinsicContentSize )不能填滿或者超出 StackView 的尺寸讹开,那就會(huì)按照 Hugging 或者 CompressionResistance 的優(yōu)先級(jí)來拉伸或壓縮一些 arrangedSubview 盅视。如果出現(xiàn)優(yōu)先級(jí)相同的情況捐名,就按排列順序來拉伸或壓縮旦万。

UIStackViewDistributionFillEqually :這種就是 StackView 的尺寸減去所有的spacing之后均分給 arrangedSubviews ,每個(gè) arrangedSubview 的尺寸是相同的镶蹋。

UIStackViewDistributionFillProportionally :這種跟FillEqually差不多成艘,只不過這個(gè)不是講尺寸均分給 arrangedSubviews ,而是根據(jù) arrangedSubviews 的 intrinsicContentSize 按比例分配贺归。

UIStackViewDistributionEqualSpacing :這種是使 arrangedSubview 之間的spacing相等淆两,但是這個(gè)spacing是有可能大于 StackView 所設(shè)置的spacing,但是絕對不會(huì)小于拂酣。這個(gè)類型的布局可以這樣理解秋冰,先按所有的 arrangedSubview 的 intrinsicContentSize 布局,然后余下的空間均分為spacing婶熬,如果大約 StackView 設(shè)置的spacing那這樣就OK了剑勾,如果小于就按照 StackView 設(shè)置的spacing,然后按照 CompressionResistance 的優(yōu)先級(jí)來壓縮一個(gè) arrangedSubview 赵颅。

UIStackViewDistributionEqualCentering :這種是使 arrangedSubview 的中心點(diǎn)之間的距離相等虽另,這樣沒兩個(gè) arrangedSubview 之間的spacing就有可能不是相等的,但是這個(gè)spacing仍然是大于等于 StackView 設(shè)置的spacing的饺谬,不會(huì)是小于捂刺。這個(gè)類型布局仍然是如果 StackView 有多余的空間會(huì)均分給 arrangedSubviews 之間的spacing,如果空間不夠那就按照 CompressionResistance 的優(yōu)先級(jí)壓縮 arrangedSubview 募寨。

4族展,alignment 子控件對其方式,類似UIlabel的textAlignment拔鹰, 可以做一個(gè)類比苛谷, UILabel對應(yīng)UIStackView, label的內(nèi)容對應(yīng)StackView的子控件格郁。

UIStackViewDistribution是個(gè)枚舉值腹殿, 各個(gè)值如下:

UIStackViewAlignmentFill, 默認(rèn)方式, 如果子控件水平布局, 則指子控件的垂直方向填充滿stackView. 反之亦然

UIStackViewAlignmentLeading, 如果子控件豎直布局, 則指子控件左邊對齊stackView左邊. 反之亦然, 即 UIStackViewAlignmentTop = UIStackViewAlignmentLeading例书。

UIStackViewAlignmentTop = UIStackViewAlignmentLeading,

UIStackViewAlignmentFirstBaseline, 根據(jù)上方基線布局所有子視圖的y值(適用于Horizontal模式)锣尉, 這種模式?jīng)]搞懂, 有知道怎么回事的求教了

UIStackViewAlignmentLastBaseline, 根據(jù)下方基線布局所有子視圖的y值(適用于Horizontal模式)

UIStackViewAlignmentCenter, 中心對齊

UIStackViewAlignmentTrailing, 如果子控件豎直布局, 則指子控件左邊對齊stackView右邊. 反之亦然, 即UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing

UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing,

四决采, 另一個(gè)有意思一點(diǎn)的示例自沧, 同時(shí)演示stackView的嵌套

即文章開頭放出的動(dòng)態(tài)圖,
這個(gè)效果使用了兩個(gè)StackView, 一個(gè)horizontalView拇厢, 一個(gè)verticalView爱谁,horizontalView即示例下方水平排布的View, 這個(gè)horizontalView也添加到verticalView的arrangedSubviews數(shù)組中孝偎, 具體實(shí)現(xiàn)看代碼吧访敌, 不多說了
github地址 : UIStackVIewDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市衣盾,隨后出現(xiàn)的幾起案子寺旺,更是在濱河造成了極大的恐慌,老刑警劉巖势决,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阻塑,死亡現(xiàn)場離奇詭異,居然都是意外死亡果复,警方通過查閱死者的電腦和手機(jī)陈莽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虽抄,“玉大人走搁,你說我怎么就攤上這事〖牵” “怎么了朱盐?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長菠隆。 經(jīng)常有香客問我兵琳,道長,這世上最難降的妖魔是什么骇径? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任躯肌,我火速辦了婚禮,結(jié)果婚禮上破衔,老公的妹妹穿的比我還像新娘清女。我一直安慰自己,他們只是感情好晰筛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布嫡丙。 她就那樣靜靜地躺著,像睡著了一般读第。 火紅的嫁衣襯著肌膚如雪曙博。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天怜瞒,我揣著相機(jī)與錄音父泳,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惠窄,可吹牛的內(nèi)容都是我干的蒸眠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼杆融,長吁一口氣:“原來是場噩夢啊……” “哼楞卡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起擒贸,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤臀晃,失蹤者是張志新(化名)和其女友劉穎觉渴,沒想到半個(gè)月后介劫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡案淋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年座韵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踢京。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡誉碴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瓣距,到底是詐尸還是另有隱情黔帕,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布蹈丸,位于F島的核電站成黄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏逻杖。R本人自食惡果不足惜奋岁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荸百。 院中可真熱鬧闻伶,春花似錦、人聲如沸够话。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽女嘲。三九已至畜份,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澡为,已是汗流浹背漂坏。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人顶别。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓谷徙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親驯绎。 傳聞我的和親對象是個(gè)殘疾皇子完慧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 目錄 0、前言 一剩失、Auto Layout前世今生 二屈尼、Auto Layout基礎(chǔ)知識(shí) 1.Auto Layout...
    浮游lb閱讀 24,482評(píng)論 3 89
  • 前言 首先,我們通過下面這張圖片引出今天的主角 大家看到了什么拴孤,是愛嗎脾歧?不,這不是愛演熟,不是愛鞭执,是滿滿的‘愁緒’???...
    一念之見閱讀 2,201評(píng)論 0 2
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫芒粹、插件兄纺、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評(píng)論 4 62
  • 翻譯自“Auto Layout Guide”。 1 入門 1.1 理解自動(dòng)布局 自動(dòng)布局根據(jù)視圖層級(jí)結(jié)構(gòu)中視圖上的...
    lakerszhy閱讀 3,580評(píng)論 3 26
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,070評(píng)論 25 707