StackView

我的博客, 各位看官有時間賞光

UIStackView

UIStackView介紹

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

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

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

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

UIStackViewDistribution

axisspacingdistributionalignment是比較重要的4個屬性,他們都能給布局帶來明顯的變化。axisspacing屬性作用單一,通過屬性解釋或者通過視圖簡單觀察我們就能理解他們的作用。distributionalignment這兩個屬性相對而言更具靈活性,也更具有難度,尤其是二者的結合使用。

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填充滿整個StackView,他們之間的間隙等于spacing大小

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

Hugging/CompressionResistance.png

UIStackViewDistributionFill.png
  • UIStackViewDistributionFillEqually

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

UIStackViewDistributionFillEqually.png
  • UIStackViewDistributionFillProportionally

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

UIStackViewDistributionFillProportionally.png
  • UIStackViewDistributionEqualSpacing

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

    如果spacing小于StackView設置的spacing,則按照CompressionResistance的優(yōu)先級來壓縮arrangedSubviews。

UIStackViewDistributionEqualSpacing.png
  • UIStackViewDistributionEqualCentering

    令arrangedSubviews的中心點之間的距離相等,且spacing大于等于StackView設置的spacing(每兩個arrangedSubview之間的spacing可能不相等)

    如果spacing小于StackView設置的spacing,則按照CompressionResistance的優(yōu)先級來壓縮arrangedSubviews。

UIStackViewDistributionEqualCentering.png

UIStackViewalignment

  • UIStackViewAlignmentFill

    在StackView軸向的垂直方向上拉伸所有子view來填充StackView

UIStackViewAlignmentFill.png
  • UIStackViewAlignmentLeading

    用于stackview是垂直軸向時,所有子view靠左對齊

UIStackViewAlignmentLeading.png
  • UIStackViewAlignmentTop

    用于stackview是水平軸向時,所有子view靠頂部對齊

UIStackViewAlignmentTop.png
  • UIStackViewAlignmentCenter

    在StackView軸向的垂直方向上子視圖以中線為基準對齊

UIStackViewAlignmentCenter.png
  • UIStackViewAlignmentTrailing

    用于stackview是垂直軸向時,所有子view靠右對齊

UIStackViewAlignmentTrailing.png
  • UIStackViewAlignmentBottom

    用于stackview是水平軸向時,所有子view靠底部對齊

UIStackViewAlignmentBottom.png
  • UIStackViewAlignmentFirstBaseline

    用于stackview是水平軸向時,按照第一個子視圖中文字的第一行對齊

UIStackViewAlignmentFirstBaseline.png
  • UIStackViewAlignmentLastBaseline

    用于stackview是水平軸向時,按照最后一個子視圖中文字的最后一行對齊

UIStackViewAlignmentLastBaseline.png

storyboard添加StackView

  • IB
  • 從對象庫中拖拽UIStackView到storyboard中,然后往內部扔控件(UIView或其子類)就可以了。
  • 選擇storyboard中的控件,可以用“command鍵 + 單擊”進行多選,然后點擊下方的stack按鈕,這樣選中的控件就會被放入一個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];
  • 動態(tài)的改變其中view的個數(shù)
UIView * newView = [[UIView alloc]init];
[stackView addArrangedSubview:newView];

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

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

StackView使用技巧

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

使用StackView 嵌套 模仿同程首頁布局

嵌套_TC.png

嵌套.png

  • 結合sizeClass 多屏幕適配
查看SatckView的Attributes Inspector,我們會發(fā)現(xiàn)StackView的幾個主要屬性都是可以設置sizeclass模式的,
這對我們的屏幕適配將會大有助益。再加上約束的sizeClass,靈活性可以想象。
多屏幕適配.png
  • 因為StackView繼承于UIView,因此在布局改變的時候,我們可以使用UIView層的動畫 添加view的時候會有動畫效果,移除的時候沒有
[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)下無法使用的問題
FDStackView之前也已經(jīng)有了一些類似的開源項目,比如OAStackViewTZStackView,然而他們都不能滿足我們的需求,局限性還是比較大的,比如不支持IB,某些功能還沒有實現(xiàn),類名需要使用非UIStackView,在我們看來這些對開發(fā)者來說都是不友好的,開發(fā)者需要的是一款功能完善,支持IB,使用時完全無感,在Xcode7上直接使用UIStackView即可,接下來的事情交給FDStackView就好,它負責將UIStackView在低于iOS9的系統(tǒng)上運行。

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

FDStackView.png

  • forkingdog開源小組的成員實現(xiàn)原理介紹
Stay Hungry. Stay Foolish
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,482評論 2 379

推薦閱讀更多精彩內容

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