iOS UIStackView 使用技巧:添加彈簧和固定長度

UIStackView 類提供了一個(gè)高效的接口用于平鋪一行或一列的視圖組合。Stack視圖管理著所有在它的 arrangedSubviews 屬性中的視圖的布局膝昆。這些視圖根據(jù)它們在 arrangedSubviews 數(shù)組中的順序沿著 Stack 視圖的軸向排列组贺。
簡而言之凸舵,即UIStackView,就是一個(gè)ContainerView失尖,可以沿橫向或縱向按照一定的規(guī)則布局內(nèi)部的子View啊奄。

1、四大屬性

UIStackView主要包括了四大屬性:axis掀潮、alignment菇夸、distribution、spacing仪吧。


  • axis:布局方向
UILayoutConstraintAxisHorizontal = 0,//水平
UILayoutConstraintAxisVertical = 1//垂直
  • alignment:非軸方向子視圖的對齊方式
UIStackViewAlignmentFill,//子視圖填充StackView
UIStackViewAlignmentLeading,//子視圖左對齊(axis為垂直方向而言)
UIStackViewAlignmentTop = UIStackViewAlignmentLeading,//子視圖頂部對齊(axis為水平方向而言)
UIStackViewAlignmentFirstBaseline, // 按照第一個(gè)子視圖的文字的第一行對齊庄新,同時(shí)保證高度最大的子視圖底部對齊(只在axis為水平方向有效)
UIStackViewAlignmentCenter,//子視圖居中對齊
UIStackViewAlignmentTrailing,//子視圖右對齊(axis為垂直方向而言)
UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing,//子視圖底部對齊(axis為水平方向而言)
UIStackViewAlignmentLastBaseline, // 按照最后一個(gè)子視圖的文字的最后一行對齊,同時(shí)保證高度最大的子視圖頂部對齊(只在axis為水平方向有效)
  • distribution:設(shè)置軸方向上子視圖的分布比例(如果axis是水平方向,也即設(shè)置子視圖的寬度择诈,如果axis是垂直方向械蹋,則是設(shè)置子視圖的高度)
UIStackViewDistributionFill = 0, 填滿,不符合則按優(yōu)先級壓縮或拉伸控件
UIStackViewDistributionFillEqually, 子控件等寬(高)
UIStackViewDistributionFillProportionally, 根據(jù)每個(gè)子視圖里面內(nèi)容的尺寸來進(jìn)行填充操作
UIStackViewDistributionEqualSpacing, 保證間距相等
UIStackViewDistributionEqualCentering, 保證每個(gè)子視圖中心直接的間距相等
  • spacing:該屬性控制子視圖之間的間隔大小羞芍,在distribution前三個(gè)屬性值設(shè)置的情況下哗戈,子視圖之間是沒有間隔,我們可以通過spacing屬性顯式的設(shè)置

2涩金、distribution 各類模式

  • UIStackViewDistributionFill:填滿
    將arrangedSubviews填充滿整個(gè)StackView谱醇,他們之間的間隙等于spacing大小暇仲。如果減去所有的spacing步做,所有arrangedSubview的固有尺寸(intrinsicContentSize)之和不能填滿StackView,那么就按照Hugging的優(yōu)先級將其拉伸奈附。反之全度,如果超出StackView的尺寸則按CompressionResistance的優(yōu)先級壓縮。如果優(yōu)先級相同斥滤,就按排列順序來拉伸或壓縮将鸵。
  • UIStackViewDistributionFillEqually:子控件等寬(高)
    每個(gè)arrangedSubview沿axis方向的長度相等,等于StackView沿axis長度減去spacing之和除以arrangedSubviews個(gè)數(shù)佑颇。
    鋪滿后如果是垂直排列所有的子視圖高度相等顶掉,如果是水平排列所有的子視圖寬度相等。
  • UIStackViewDistributionFillProportionally:按比例分配剩余空間
    根據(jù)每個(gè)子視圖里面內(nèi)容的尺寸來進(jìn)行填充操作挑胸。
    根據(jù)arrangedSubview的intrinsicContentSize(原本尺寸)痒筒,將StackView沿axis方向的長度減去spacing之和按比例分配給arrangedSubviews。
  • UIStackViewDistributionEqualSpacing:保證間距相等
    先按arrangedSubviews的intrinsicContentSize(原本尺寸)布局茬贵,然后余下的空間均分為spacing簿透,如果spacing小于StackView設(shè)置的spacing,則按照CompressionResistance的優(yōu)先級來壓縮arrangedSubviews解藻。
  • UIStackViewDistributionEqualCentering:中點(diǎn)之間等距離
    令arrangedSubviews的中心點(diǎn)之間的距離相等老充,且spacing大于等于StackView設(shè)置的spacing(每兩個(gè)arrangedSubview之間的spacing可能不相等)。如果spacing小于StackView設(shè)置的spacing螟左,則按照CompressionResistance的優(yōu)先級來壓縮arrangedSubviews啡浊。

3、使用技巧

3.1> 善用嵌套

只要嵌套好UIStackView胶背,就可以用很少的約束達(dá)到自動布局界面的目的巷嚣。

3.2> 增量排版

如果排版比較復(fù)雜,不建議使用系統(tǒng)的 spacing 屬性奄妨,可以生成透明視圖來占位涂籽,約束視圖大小就可以達(dá)到控制子視圖間距的效果。

  • 固定長度:利用約束透明視圖的寬(高)度實(shí)現(xiàn)砸抛。
  • 彈簧:利用約束透明視圖的優(yōu)先級來實(shí)現(xiàn)评雌。
    • 如果兩邊都使用彈簧物臂,需要再將彈簧約束為等寬(高)
// 占位視圖宏定義
#define StackFixed(w, h) \
^{\
    UIView *view = UIView.new;\
    [view mas_makeConstraints:^(MASConstraintMaker *make) {\
        if (w > 0) make.width.mas_equalTo(w);\
        if (h > 0) make.height.mas_equalTo(h);\
    }];\
    return view;\
}()

// 彈簧宏定義
#define StackSpring(axis) \
^{\
    UIView *view = UIView.new; \
    [view mas_makeConstraints:^(MASConstraintMaker *make) {\
        if (axis == UILayoutConstraintAxisHorizontal) {\
            make.width.mas_equalTo(1000).priorityLow();\
        } else {\
            make.height.mas_equalTo(1000).priorityLow();\
        }\
    }];\
    return view;\
}()

Demo地址StackViewDemo


iOS11 新增api

可以定制各個(gè)子控件后面的間距券册,但使用起來需要考慮版本適配的問題。

/* Set and get custom spacing after a view. 
 
 This custom spacing takes precedence over any other value that might otherwise be used 
 for the space following the arranged subview.
 
 Defaults to UIStackViewSpacingUseDefault (Swift: UIStackView.spacingUseDefault), where 
 resolved value will match the spacing property.
 
 You may also set the custom spacing to UIStackViewSpacingUseSystem (Swift: UIStackView.spacingUseSystem),
 where the resolved value will match the system-defined value for the space to the neighboring view, 
 independent of the spacing property.
 
 Maintained when the arranged subview changes position in the stack view, but not after it
 is removed from the arrangedSubviews list.
 
 Ignored if arrangedSubview is not actually an arranged subview.
 */
- (void)setCustomSpacing:(CGFloat)spacing afterView:(UIView *)arrangedSubview API_AVAILABLE(ios(11.0),tvos(11.0));
- (CGFloat)customSpacingAfterView:(UIView *)arrangedSubview API_AVAILABLE(ios(11.0),tvos(11.0));
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市窘奏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辕漂,老刑警劉巖黍图,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異和措,居然都是意外死亡庄呈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門派阱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诬留,“玉大人,你說我怎么就攤上這事贫母∥亩遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵腺劣,是天一觀的道長绿贞。 經(jīng)常有香客問我,道長橘原,這世上最難降的妖魔是什么籍铁? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮靠柑,結(jié)果婚禮上寨辩,老公的妹妹穿的比我還像新娘。我一直安慰自己歼冰,他們只是感情好靡狞,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著隔嫡,像睡著了一般甸怕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腮恩,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天梢杭,我揣著相機(jī)與錄音,去河邊找鬼秸滴。 笑死武契,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咒唆,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼届垫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了全释?” 一聲冷哼從身側(cè)響起装处,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浸船,沒想到半個(gè)月后妄迁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡李命,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年登淘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片项戴。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡形帮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出周叮,到底是詐尸還是另有隱情,我是刑警寧澤界斜,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布仿耽,位于F島的核電站,受9級特大地震影響各薇,放射性物質(zhì)發(fā)生泄漏项贺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一峭判、第九天 我趴在偏房一處隱蔽的房頂上張望开缎。 院中可真熱鬧,春花似錦林螃、人聲如沸奕删。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽完残。三九已至,卻和暖如春横漏,著一層夾襖步出監(jiān)牢的瞬間谨设,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工缎浇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扎拣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像二蓝,于是被迫代替她去往敵國和親尊蚁。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345