StackView

我的博客, 各位看官有時(shí)間賞光

UIStackView

UIStackView介紹

隨著autolayout的推廣開(kāi)來(lái),更多的app開(kāi)始使用自動(dòng)布局的方式來(lái)構(gòu)建自己的UI系統(tǒng),autolayout配合storyBoard和一些第三方的框架,對(duì)于創(chuàng)建約束來(lái)說(shuō),已經(jīng)十分方便,但是對(duì)于一些動(dòng)態(tài)的線(xiàn)性布局的視圖,我們需要手動(dòng)添加的約束不僅非常多,而且如果我們需要插入或者移除其中的一些UI元素的時(shí)候,我們又要做大量的修改約束的工作,UIStackView正好可以解決這樣的問(wèn)題。

UIStackViewiOS 9 中新增的一個(gè)控件,它繼承于UIView,用來(lái)管理一行或一列視圖的布局(堆疊視圖的控制器類(lèi)視圖,所謂堆疊視圖時(shí)一種平鋪式的線(xiàn)性布局方式,不可重疊,布局方向也不可交錯(cuò))。UIStackView新增了幾個(gè)屬性,這些屬性就是子視圖布局規(guī)則。一旦UIStackView的這些屬性發(fā)生變化,它的arrangedSubviews就會(huì)按照規(guī)則重新排布。只要我們掌握這些規(guī)則,就可以管理視圖布局了。如果能再稍加靈活運(yùn)用,有時(shí)候我們甚至能輕松實(shí)現(xiàn)一些精妙布局。 UIStackView可以幫助開(kāi)發(fā)者更加簡(jiǎn)單的使用layout而不必手動(dòng)添加太多布局約束.

屬 性 作 用
Axis 屬性決定了 stack 的朝向,只有垂直或水平
distribution 屬性決定了其管理的視圖在沿著其軸向上的布局
Alignment 屬性決定了其管理的視圖在垂直于其軸向上的布局
Spacing 屬性決定了其管理的視圖間的最小間隙
layoutMarginsRelativeArrangement 屬性決定了 stack 視圖平鋪其管理的視圖時(shí)是否要參照它的布局邊距
baselineRelativeArrangement 屬性決定了 stack 視圖平鋪其管理的視圖時(shí)是否要參照它的布局邊距

![Uploading 19_081418.png . . .]
](http://upload-images.jianshu.io/upload_images/1129706-a300c78a3ddc0cdb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

UIStackViewDistribution

axisspacing、distributionalignment是比較重要的4個(gè)屬性,他們都能給布局帶來(lái)明顯的變化。axisspacing屬性作用單一,通過(guò)屬性解釋或者通過(guò)視圖簡(jiǎn)單觀(guān)察我們就能理解他們的作用。distributionalignment這兩個(gè)屬性相對(duì)而言更具靈活性,也更具有難度,尤其是二者的結(jié)合使用。

public enum UIStackViewDistribution : Int {
  case fill
  case fillEqually
  case fillProportionally
  case equalSpacing
  case equalCentering
}

public enum UIStackViewAlignment : Int {
  case fill   
  case leading
  public static var top: UIStackViewAlignment { get }
  case firstBaseline
  case center
  case trailing
  public static var bottom: UIStackViewAlignment { get }
  case lastBaseline 
}
  • UIStackViewDistributionFill

將arrangedSubviews填充滿(mǎn)整個(gè)StackView,他們之間的間隙等于spacing大小

如果減去所有的spacing,所有arrangedSubview的固有尺寸(intrinsicContentSize)之和不能填滿(mǎn)StackView,那么就按照Hugging的優(yōu)先級(jí)將其拉伸。反之,如果超出StackView的尺寸則按CompressionResistance的優(yōu)先級(jí)壓縮。如果優(yōu)先級(jí)相同,就按排列順序來(lái)拉伸或壓縮。

Hugging/CompressionResistance.png

UIStackViewDistributionFill.png
  • UIStackViewDistributionFillEqually

每個(gè)arrangedSubview沿axis方向的長(zhǎng)度相等,等于StackView沿axis長(zhǎng)度減去spacing之和除以arrangedSubviews個(gè)數(shù)。

UIStackViewDistributionFillEqually.png
  • UIStackViewDistributionFillProportionally

    根據(jù)arrangedSubview的intrinsicContentSize,將StackView沿axis方向的長(zhǎng)度減去spacing之和按比例分配給arrangedSubviews。

UIStackViewDistributionFillProportionally.png
  • UIStackViewDistributionEqualSpacing

    先按arrangedSubviews的intrinsicContentSize布局,然后余下的空間均分為spacing

    如果spacing小于StackView設(shè)置的spacing,則按照CompressionResistance的優(yōu)先級(jí)來(lái)壓縮arrangedSubviews。

UIStackViewDistributionEqualSpacing.png
  • UIStackViewDistributionEqualCentering

    令arrangedSubviews的中心點(diǎn)之間的距離相等,且spacing大于等于StackView設(shè)置的spacing(每?jī)蓚€(gè)arrangedSubview之間的spacing可能不相等)

    如果spacing小于StackView設(shè)置的spacing,則按照CompressionResistance的優(yōu)先級(jí)來(lái)壓縮arrangedSubviews。

UIStackViewDistributionEqualCentering.png

UIStackViewalignment

  • UIStackViewAlignmentFill

    在StackView軸向的垂直方向上拉伸所有子view來(lái)填充StackView

UIStackViewAlignmentFill.png
  • UIStackViewAlignmentLeading

    用于stackview是垂直軸向時(shí),所有子view靠左對(duì)齊

UIStackViewAlignmentLeading.png
  • UIStackViewAlignmentTop

    用于stackview是水平軸向時(shí),所有子view靠頂部對(duì)齊

UIStackViewAlignmentTop.png
  • UIStackViewAlignmentCenter

    在StackView軸向的垂直方向上子視圖以中線(xiàn)為基準(zhǔn)對(duì)齊

UIStackViewAlignmentCenter.png
  • UIStackViewAlignmentTrailing

    用于stackview是垂直軸向時(shí),所有子view靠右對(duì)齊

UIStackViewAlignmentTrailing.png
  • UIStackViewAlignmentBottom

    用于stackview是水平軸向時(shí),所有子view靠底部對(duì)齊

UIStackViewAlignmentBottom.png
  • UIStackViewAlignmentFirstBaseline

    用于stackview是水平軸向時(shí),按照第一個(gè)子視圖中文字的第一行對(duì)齊

UIStackViewAlignmentFirstBaseline.png
  • UIStackViewAlignmentLastBaseline

    用于stackview是水平軸向時(shí),按照最后一個(gè)子視圖中文字的最后一行對(duì)齊

UIStackViewAlignmentLastBaseline.png

storyboard添加StackView

  • IB
  • 從對(duì)象庫(kù)中拖拽UIStackView到storyboard中,然后往內(nèi)部扔控件(UIView或其子類(lèi))就可以了。
  • 選擇storyboard中的控件,可以用“command鍵 + 單擊”進(jìn)行多選,然后點(diǎn)擊下方的stack按鈕,這樣選中的控件就會(huì)被放入一個(gè)StackView中。
storyboard.png

代碼添加StackView

  • 創(chuàng)建UIStackView
    UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[forkingLabel, logoImageView, dogLabel]];
    stackView.translatesAutoresizingMaskIntoConstraints = NO;
    stackView.axis = UILayoutConstraintAxisHorizontal;
    stackView.distribution = UIStackViewDistributionFill;
    stackView.alignment = UIStackViewAlignmentCenter;
    stackView.spacing = 0;
   [self.view addSubview:stackView];
  • 動(dòng)態(tài)的改變其中view的個(gè)數(shù)
UIView * newView = [[UIView alloc]init];
[stackView addArrangedSubview:newView];

特別注意addArrangedSubviewaddSubview有很大的區(qū)別,使用前者是將視圖添加進(jìn)StackView的布局管理,后者只是簡(jiǎn)單的加在視圖的層級(jí)上,并不接受StackView的布局管理。

  • 與之相對(duì),我們可以使用下面的方法移除一個(gè)view
UIView * view = [stackView arrangedSubviews].lastObject;
[stackView removeArrangedSubview:view];

StackView使用技巧

  • 嵌套 只要嵌套好UIStackView,就可以用很少的約束達(dá)到自動(dòng)布局界面的目的

使用StackView 嵌套 模仿同程首頁(yè)布局

嵌套_TC.png

嵌套.png

  • 結(jié)合sizeClass 多屏幕適配
查看SatckView的Attributes Inspector,我們會(huì)發(fā)現(xiàn)StackView的幾個(gè)主要屬性都是可以設(shè)置sizeclass模式的,
這對(duì)我們的屏幕適配將會(huì)大有助益。再加上約束的sizeClass,靈活性可以想象。
多屏幕適配.png
  • 因?yàn)?code>StackView繼承于UIView,因此在布局改變的時(shí)候,我們可以使用UIView層的動(dòng)畫(huà) 添加view的時(shí)候會(huì)有動(dòng)畫(huà)效果,移除的時(shí)候沒(méi)有
[stackView addArrangedSubview:newView];
[UIView animateWithDuration:1 animations:^{
[stackView layoutIfNeeded];
}];

stackView_gif.gif

FDStackView

UIStackView是在iOS9才推出的,最低支持的系統(tǒng)也是iOS9, FDStackView出現(xiàn)了,它就是為了解決UIStackView在低于iOS9的系統(tǒng)下無(wú)法使用的問(wèn)題
FDStackView之前也已經(jīng)有了一些類(lèi)似的開(kāi)源項(xiàng)目,比如OAStackViewTZStackView,然而他們都不能滿(mǎn)足我們的需求,局限性還是比較大的,比如不支持IB,某些功能還沒(méi)有實(shí)現(xiàn),類(lèi)名需要使用非UIStackView,在我們看來(lái)這些對(duì)開(kāi)發(fā)者來(lái)說(shuō)都是不友好的,開(kāi)發(fā)者需要的是一款功能完善,支持IB,使用時(shí)完全無(wú)感,在Xcode7上直接使用UIStackView即可,接下來(lái)的事情交給FDStackView就好,它負(fù)責(zé)將UIStackView在低于iOS9的系統(tǒng)上運(yùn)行。

需要注意如果使用IB的話(huà),那么IBBuilds for屬性需要設(shè)置為iOS 9.0 and later

FDStackView.png

  • forkingdog開(kāi)源小組的成員實(shí)現(xiàn)原理介紹
Stay Hungry. Stay Foolish
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • StackView們 UIStackView是iOS9新引入的控件。它支持垂直和水平排列多個(gè)子視圖(SubView...
    取水閱讀 5,403評(píng)論 1 11
  • StackView學(xué)習(xí) 自適應(yīng)、適配、布局這幾個(gè)關(guān)鍵詞一直伴隨著iOS開(kāi)發(fā),從以前的單一尺寸屏幕,到現(xiàn)在的多尺寸屏...
    simuty閱讀 1,548評(píng)論 4 2
  • UIStackView 類(lèi)提供了一個(gè)高效的接口用于平鋪一行或一列的視圖組合。Stack視圖使你依靠自動(dòng)布局的能力,...
    Chivalrous閱讀 911評(píng)論 1 2
  • 前言 首先,我們通過(guò)下面這張圖片引出今天的主角 大家看到了什么,是愛(ài)嗎?不,這不是愛(ài),不是愛(ài),是滿(mǎn)滿(mǎn)的‘愁緒’???...
    一念之見(jiàn)閱讀 2,331評(píng)論 0 2
  • 這篇文章緊跟上邊autolayout的一些小技巧,如果你沒(méi)有看過(guò),不防先看下《你真的會(huì)用autolayout...
    檻內(nèi)濁物閱讀 10,473評(píng)論 7 46

友情鏈接更多精彩內(nèi)容