iOS9 UIStackView 簡(jiǎn)介

作者:Umberto Raimondi,原文鏈接,原文日期:2015-12-08
譯者:CoderAFI;校對(duì):Channe姆吭;定稿:shanks

示例程序采用 Swift2.0 編寫,需要用 Xcode7 進(jìn)行編譯唁盏,可以訪問 Github 或者 zipped 下載本文源代碼

iOS9 新加入了一個(gè)非常易用的布局控件 UIStackView内狸,它可以將一組 UIView 視圖進(jìn)行垂直或水平方向的排列,用來(lái)替換手工使用 Auto Layout 對(duì)視圖進(jìn)行布局升敲。

每個(gè) UIStackView 控件都可以在垂直和水平方向上排列展示一組 subviews答倡,并可以根據(jù)當(dāng)前屏幕大小和方向的變化動(dòng)態(tài)調(diào)整它的內(nèi)容,感覺起來(lái)就像是一個(gè)隱形的容器驴党。實(shí)際上 subviews 的位置是根據(jù)設(shè)置的對(duì)齊瘪撇、間距和大小屬性來(lái)決定的。

內(nèi)部的原理是 UIStackView 類幫你管理了 Auto Layout 約束港庄。想象一下 UIStackView 其實(shí)就是一個(gè)基于 Auto Layout 的抽象層從而使布局屬性的創(chuàng)建簡(jiǎn)單化倔既。你可以在一個(gè)主 UIStackView 中嵌套 UIStackView 從而讓視圖精確放置到相應(yīng)的位置。

如果你做過 Android 開發(fā)鹏氧,你會(huì)發(fā)現(xiàn) UIStackView 概念跟 Android 中最常用的布局控件 LinearLayout 非常相似渤涌,這些布局的想法其實(shí)都是從早期的 Java Swing 開發(fā)中借鑒過來(lái)并加以完善的。

基礎(chǔ)

UIStackView 既可以用代碼編寫也可以在 Interface Builder 中設(shè)計(jì)把还。

在 Interface Builder 中你可以從 Object Library 控件選擇工具集里找到垂直或者水平對(duì)齊的 UIStackView 并添加到相應(yīng)位置实蓬,然后就可以在 UIStackView 上添加新的視圖了茸俭。

UIStackView 同樣也可以對(duì)現(xiàn)有的一些視圖進(jìn)行包裝,只需要選擇他們并點(diǎn)擊 Interface Builder 底部工具欄新加的
Stack icon
Stack icon

圖標(biāo)即可安皱。

非常簡(jiǎn)單调鬓,但是我們的教程將用代碼的方式實(shí)現(xiàn)一個(gè)簡(jiǎn)單的嵌套布局。

在這個(gè)簡(jiǎn)單的示例程序中酌伊,我們將會(huì)在狀態(tài)欄下放置一個(gè) UIStackView腾窝,里面包含四個(gè)控件:兩個(gè) UILabel,一個(gè)水平方向的 UIStackView 和 一個(gè) UIButton居砖。水平方向的 UIStackView 中包含了三個(gè)帶有默認(rèn)圖標(biāo)的按鈕虹脯。

下面讓我們創(chuàng)建一個(gè) Single View Application,記住要將 Deployment Target 設(shè)置成 9.0+奏候。

打開 ViewController 類并用下面的代碼替換 viewDidLoad 方法:

var stackView:UIStackView!
var nestedStackView = UIStackView()

override func viewDidLoad() {
    super.viewDidLoad()

    stackView.translatesAutoresizingMaskIntoConstraints=false
    self.view.addSubview(stackView)
    // Main UIStackView contraints, nearly fills its parent view
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-30-[stackView]-30-|",options: NSLayoutFormatOptions.AlignAllLeading,metrics: nil, views: ["stackView":stackView]))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[stackView]-10-|",options: NSLayoutFormatOptions.AlignAllLeading,metrics: nil, views: ["stackView":stackView]))

    stackView.axis = .Vertical
    stackView.alignment = .Fill
    stackView.spacing = 25
    stackView.distribution = .FillEqually

    var lbl = UILabel()
    lbl.text ="Label 1"
    lbl.backgroundColor = UIColor.redColor()
    stackView.addArrangedSubview(lbl)

    lbl = UILabel()
    lbl.text = "Label 2"
    lbl.backgroundColor = UIColor.greenColor()
    stackView.addArrangedSubview(lbl)

    nestedStackView.axis = .Horizontal
    nestedStackView.alignment = .Fill
    nestedStackView.spacing = 25
    nestedStackView.distribution = .FillEqually
    nestedStackView.addArrangedSubview(UIButton(type: .InfoDark))
    nestedStackView.addArrangedSubview(UIButton(type: .InfoLight))
    nestedStackView.addArrangedSubview(UIButton(type: .ContactAdd))
    stackView.addArrangedSubview(nestedStackView)

    let btn = UIButton(type: .System)
    btn.setTitle("Press Me", forState: .Normal)
    stackView.addArrangedSubview(btn)
}

為了指定主 UIStackView 是垂直方向布局的我們把 axis 屬性設(shè)置成 .Vertical循集,前三個(gè)控件將會(huì)等間距排列,剩下的UIButton會(huì)填充剩余的可用空間蔗草。在嵌套 UIStackView 中的三個(gè)默認(rèn)按鈕也是用同樣的方式來(lái)排列暇榴。alignmentdistribution蕉世、spacing 三個(gè)屬性會(huì)在下面單獨(dú)講解,這里我們先忽略它們婆硬。

有時(shí)候你可能需要將部分視圖隱藏起來(lái)或者顯示出來(lái)狠轻,這對(duì)于 UIStackView 來(lái)說(shuō)實(shí)現(xiàn)起來(lái)是非常容易的,你只需要設(shè)置相應(yīng)視圖的 hidden 屬性就可以彬犯。

為了方便測(cè)試向楼,我們給 UIButton 添加一個(gè) pressedMe 的點(diǎn)擊事件響應(yīng)方法:

    ...
    btn.setTitle("Press Me", forState: .Normal)
    btn.addTarget(self, action: "pressedMe:", forControlEvents: UIControlEvents.TouchUpInside)
    stackView.addArrangedSubview(btn)

}

func pressedMe(sender: UIButton!){
    UIView.animateWithDuration(0.5) {
        self.nestedStackView.hidden = !self.nestedStackView.hidden
    }
}

當(dāng)點(diǎn)擊這個(gè)按鈕時(shí),主 UISTackView 和 內(nèi)部的 UISTackView 將會(huì)根據(jù)在 viewDidLoad 中設(shè)置的屬性重新布局內(nèi)部的子視圖并帶有短暫的顯示或者隱藏動(dòng)畫效果谐区。

如果需要湖蜕,subviews 也可以完全從 UIStackView 中移除然后剩下的子視圖也會(huì)根據(jù)各自的屬性重新布局。

func pressedMe(sender: UIButton!){
   stackView.removeArrangedSubview(nestedStackView)
   nestedStackView.removeFromSuperview()
}

這個(gè)移除的操作需要兩步宋列,第一步是調(diào)用 removeArrangedSubview 方法用來(lái)從 UIStackView 刪除視圖并且重新布局剩余的 subviews 但是實(shí)際上并沒有從父視圖上刪除昭抒。第二部就是調(diào)用 removeFromSuperview 方法以保證該視圖從父視圖中完全的被刪除。

UIStackView: Alignment, Distribution And Spacing 屬性

下面讓我們?cè)敿?xì)了解下 UIStackView 的布局屬性:

StackProperty
StackProperty

Axis 軸

定義子視圖的布局方向炼杖,包含 Vertical(垂直) 和 Horizontal(水平)兩個(gè)枚舉值灭返。

Alignment 對(duì)齊

alignment 屬性指定了子視圖在布局方向上的對(duì)齊方式,如果值是 Fill 則會(huì)調(diào)整子視圖以適應(yīng)空間變化坤邪,其他的值不會(huì)改變視圖的大小熙含。有效的值包含:Fill、 Leading艇纺、 Top怎静、 FirstBaseline邮弹、 Center、 Trailing蚓聘、 Bottom腌乡、 LastBaseline。

Distribution 分布

Distribution 屬性定義了 subviews 的分布方式或粮,可以賦值的5個(gè)枚舉值可以分為兩組: Fill 組 和 Spacing 組导饲。

Fill 組用來(lái)調(diào)整 subviews 的大小,同時(shí)結(jié)合 spacing 屬性來(lái)確定 subviews 之間的間距氯材。

  • Fill: subviews 將會(huì)根據(jù)自己內(nèi)容的內(nèi)容阻力(content resistance)或者內(nèi)容吸附優(yōu)先級(jí)(hugging priority)進(jìn)行動(dòng)態(tài)拉伸渣锦,如果沒有設(shè)置該值,subviews 中的一個(gè)子視圖將會(huì)用來(lái)填充剩余可用空間氢哮。

  • FillEqually: 忽略其他的約束袋毙,subviews 將會(huì)在設(shè)置的布局方向上等寬或等高排列。

  • FillProportionally: subviews 將會(huì)根據(jù)自己的原始大小做適當(dāng)?shù)牟季终{(diào)整冗尤。

Spacing 組指定了 subviews 在布局方向上的間距填充方式听盖,當(dāng) subviews 不滿足布局條件或有不明確的的 Auto Layout 設(shè)置時(shí),該類型的值就會(huì)結(jié)合相應(yīng)的壓縮阻力(compression resistance) 來(lái)改變 subviews 的大小裂七。

  • EqualSpacing: subviews 等間距排列

  • EqualCentering: 在布局方向上居中的 subviews 等間距排列

Spacing 間距

spacing 屬性根據(jù)當(dāng)前 distribution 屬性的值有不同方向的解釋皆看。

如果 UIStackView 的 distribution 屬性設(shè)置的是 EqualSpacing、 EqualCentering背零,spacing 屬性指的就是 subviews 之間的最小間距腰吟。相反如果設(shè)置的是 FillProportionally 屬性,那么 spacing 的值就是嚴(yán)格的間距值徙瓶。

iOS7+ 兼容

官方的 UIStackView 只在 iOS9 以上系統(tǒng)可以使用毛雇,但是其他的開源組織在低版本的系統(tǒng)上也實(shí)現(xiàn)了相應(yīng)的功能:

本文由 SwiftGG 翻譯組翻譯,已經(jīng)獲得作者翻譯授權(quán)侦镇,最新文章請(qǐng)?jiān)L問 http://swift.gg灵疮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市壳繁,隨后出現(xiàn)的幾起案子震捣,更是在濱河造成了極大的恐慌,老刑警劉巖闹炉,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伍派,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡剩胁,警方通過查閱死者的電腦和手機(jī)诉植,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)昵观,“玉大人晾腔,你說(shuō)我怎么就攤上這事舌稀。” “怎么了灼擂?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵壁查,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我剔应,道長(zhǎng)睡腿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任峻贮,我火速辦了婚禮席怪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纤控。我一直安慰自己挂捻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布船万。 她就那樣靜靜地躺著刻撒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪耿导。 梳的紋絲不亂的頭發(fā)上声怔,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音舱呻,去河邊找鬼捧搞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛狮荔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播介粘,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼殖氏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了姻采?” 一聲冷哼從身側(cè)響起雅采,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慨亲,沒想到半個(gè)月后婚瓜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刑棵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年巴刻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛉签。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胡陪,死狀恐怖沥寥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情柠座,我是刑警寧澤邑雅,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站妈经,受9級(jí)特大地震影響淮野,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吹泡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一骤星、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荞胡,春花似錦妈踊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至萝勤,卻和暖如春露筒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背敌卓。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工慎式, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趟径。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓瘪吏,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蜗巧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子掌眠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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