從iOS9開始,蘋果提供了UIStackView來幫助咱們作佈局,這玩意兒相似於安卓的線性佈局。由於在使用過程當中會遇到一些坑,因此寫出來供遇到一樣問題的人蔘考。我在這裏提供xib和純代碼兩種方式建立使用 UIStackView:工具
先看一下運行效果:佈局
垂直方向,在圖一里,label被拉伸了,在圖2裏面,label和image被壓縮了spa
一、xib方式orm
打開storyboard以後會發現右下角多了一個圖標:ci
在xib中建立 UIStackView 要用到這個按鈕,就稱它爲 stack 按鈕吧。it
首先拖三個控件進來:io
而後按住 command鍵,而後選中這三個View,而後點擊右下角的哪一個 stack 按鈕。這時候就建立了一個 UIStackView,這個stackView包括了剛纔選中的三個View:command
圖裏面綠色箭頭指向的就是咱們剛剛建立的UIStackView。im
而右上角的紅色箭頭指向的錯誤讓人糾結了。致使錯誤的緣由有多個,咱們來一個一個的解決。img
第一個緣由:stackView沒有約束。
說來奇怪,使用xib建立UIStackView的時候,不能設置 stackview的frame,你看是灰色的:
沒辦法,不能設置frame,那就設置約束吧,選中stackView,而後給它添加約束以下:
而後咱們看一下結果如何:
效果馬馬虎虎了,但是TNND仍是有錯誤:
點進入看給的錯誤信息,大概意思是須要設置抗壓縮等級——這是啥?
這還得從 UIStackView 的排布方式提及,選中stackView,在右側工具欄查看這個:
挨個說說,
Axis(軸):這裏表明stackView所包含的View的排布方向,有豎直和水平兩種,這玩意兒比較智能,在你添加的時候可以自動判斷。你也能夠咋這裏更改。
Alignment(對齊方式):是指stackview所包含的View的對其方式,有下面幾種方式:
Fill:子View填充 stackView,它會使子View在水平和垂直方向都填充stackView
Leading:靠左對其
Trailing:靠右對齊
Center:中心對齊
Top:頂部對齊
Bottom:底部對其
Distribution(分佈):是指 stackview 的子 View的排布方式,有下面幾種方式:
Fill:默認方式,子View加起來田中整個 stackview
Fill Equally:子View的高度/寬度一致(具體是哪個一致得看是水平排布仍是垂直排布)
Fill Proportionally:StackView 本身計算出它人爲合適的排布方式,合理分配寬/高
Equal Spacing:子View保持同等間隔的排布方式
Equal Centering:每一個子View的中心線之間距離相同的排布方式,每一個子view的寬/高會適配其內容
之因此會出現上面的錯誤,是因爲 Fill、Equal Spacing 這兩個方式不能自動地對子View進行壓縮/拉伸(在子View填充的大小與stackview不符合的狀況下)。例如本文的狀況,子View的大小加起來比stackView要大,而在Fill模式下,系統又不知道該壓縮哪個View,因此才報了錯。加入將Fill模式換成 Fill Equally、Fill Proportionlly、Equal Centering就不會出錯了。
下面來解決上面的這個問題:
首先在右側的工具欄選中尺子
在裏面找到下面這兩個東西:
三個子View都有這兩個屬性
Content Hugging Priority:壓縮優先等級,這個值越低,越容易被拉伸
Content Compression Resistance Priority:抗壓縮優先等級,這個值越低越容易被壓縮
因此將其中一個View的上面這兩個屬性調低,使這個View可以被壓縮/拉伸,就能夠解決上面的問題了
例如,將label的調低,就能解決問題了
----ps,感受xib使用stackView仍是有一些問題的
二、代碼的方式:
func createStackView(){
//使用代碼的方式建立stack的時候是可使用frame的,固然,也可使用約束
let stack = UIStackView(frame: CGRect(x: 10, y: 20, width: 300, height: 600))
let btn = UIButton(type: UIButtonType.Custom)
btn.backgroundColor = UIColor.greenColor()
btn.setTitle("btnbtn", forState: UIControlState.Normal)
btn.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
stack.addArrangedSubview(btn)
let label = UILabel()
label.backgroundColor = UIColor.lightGrayColor()
label.text = "aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjjkkkklllmmmnnn"
label.numberOfLines = 0
stack.addArrangedSubview(label)
let img = UIImageView()
img.image = UIImage(named: "2")
stack.addArrangedSubview(img)
stack.alignment = UIStackViewAlignment.Center
stack.axis = UILayoutConstraintAxis.Vertical
//下面這兩行是Fill模式的
stack.distribution = UIStackViewDistribution.Fill
label.setContentHuggingPriority(249, forAxis: UILayoutConstraintAxis.Vertical)
// stack.distribution = UIStackViewDistribution.FillEqually
// stack.distribution = UIStackViewDistribution.FillProportionally
// stack.distribution = UIStackViewDistribution.EqualSpacing
self.view.addSubview(stack)
print(">>>>>>")
}