๊ธ€ ์ž‘์„ฑ์ž: ์ด์ง€์›๐ŸŒฉ๏ธ

์ด๋ฒˆ์— UI ๊ตฌ์„ฑํ•˜๋ฉด์„œ ์Šคํƒ ๋ทฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด๋ฏธ ํ•œ ๋ฒˆ ๋ณธ ๋‚ด์šฉ์ธ๋ฐ๋„, ๋ง‰์ƒ ๋‹ค์‹œ ํ•˜๋ ค๋‹ˆ๊นŒ ์–ด๋ ต๊ณ , ํ—ท๊ฐˆ๋ ค์„œ ๋‹ค์‹œ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ–ˆ๋‹ค.

UIStackView

@MainActor class UIStackView: UIView

A streamlined interface for laying out a collection of views in either a column or a row.

์—ด์ด๋‚˜ ํ–‰์— ๋ทฐ ์ปฌ๋ ‰์…˜์„ ๋ฐฐ์น˜ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ„์†Œํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ๊ฐ€๋กœ๋‚˜ ์„ธ๋กœ๋กœ ๋ ˆ์ด์•„์›ƒ์„ ๋ฐฐ์น˜ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์Šคํƒ ๋ทฐ ๋‚ด๋ถ€์— ๋‹ค๋ฅธ ์Šคํƒ ๋ทฐ๋ฅผ ์ค‘์ฒฉํ•ด์„œ ๋” ๋ณต์žกํ•œ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. Android์˜ LinearLayout๊ณผ ์œ ์‚ฌํ•˜๋‹ค.

์˜คํ†  ๋ ˆ์ด์•„์›ƒ์œผ๋กœ ์ง์ ‘ ์žก์•„์ค„ ์ˆ˜๋„ ์žˆ๋Š” ๊ฑด๋ฐ, ์ด๊ฑธ ์“ฐ๋ฉด ๋ญ๊ฐ€ ์ข‹๋ƒ? → ์žฅ์น˜์˜ ๋ฐฉํ–ฅ, ํ™”๋ฉด ํฌ๊ธฐ, ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋™์ ์œผ๋กœ ๋ฐ˜์‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

UIStackView๋Š” arrangedSubviews ํ”„๋กœํผํ‹ฐ์— ์žˆ๋Š” ๋ชจ๋“  ๋ทฐ์˜ ๋ ˆ์ด์•„์›ƒ์„ ๊ด€๋ฆฌํ•œ๋‹ค. ์ถ”๊ฐ€ํ•œ ์ˆœ์„œ๋Œ€๋กœ ์Šคํƒ ๋ทฐ ๋‚ด์—์„œ ์ •๋ ฌ๋œ๋‹ค.

๐Ÿ’ก ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒ์œ„ ๋ทฐ์— ํ•˜์œ„ ๋ทฐ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ `addSubview(_ view: UIView)` ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ฌ๋ฆฌ `UIStackView`๋Š” `addArrangedSubview(_ view: UIView)`๋ฅผ ์ด์šฉํ•œ๋‹ค.

์Šคํƒ๋ทฐ๋Š” ์ฃผ์š” 4๊ฐ€์ง€ ์†์„ฑ์— ์˜ํ•ด ๋ ˆ์ด์•„์›ƒ์ด ๋ณ€๊ฒฝ๋œ๋‹ค.

axis

์ˆ˜ํ‰ ๋˜๋Š” ์ˆ˜์ง์œผ๋กœ ์Šคํƒ์˜ ๋ฐฉํ–ฅ์„ ๊ฒฐ์ •ํ•œ๋‹ค. ๊ธฐ๋ณธ ๊ฐ’์€ ์ˆ˜ํ‰์ด๋‹ค.

vertical

horizontal

distribution

์Šคํƒ ๋ทฐ์˜ ์ถ•(axis)์˜ ๋”ฐ๋ผ ์ •๋ ฌ๋œ ๋ทฐ์˜ ๋ ˆ์ด์•„์›ƒ์„ ์ •์˜ํ•œ๋‹ค. ๊ธฐ๋ณธ ๊ฐ’์€ fill์ด๋‹ค.

์‚ฌ์‹ค ์ด๊ฑฐ๋งŒ ๋ด์„œ๋Š” ์ดํ•ด๊ฐ€ ์•ˆ ๊ฐ€๋‹ˆ๊นŒ ํ•˜๋‚˜ํ•˜๋‚˜ ์‚ดํŽด๋ณด์ž.

fill

์Šคํƒ ๋ทฐ๊ฐ€ ์Šคํƒ ๋ทฐ์˜ ์ถ•์„ ๋”ฐ๋ผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ณต๊ฐ„์„ ์ฑ„์šฐ๋„๋ก ์ •๋ ฌ๋œ ๋ทฐ(arrangedSubviews)์˜ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ์ด๋‹ค. ๊ฐ ๋ทฐ์˜ CHCR์— ๋”ฐ๋ผ ์กฐ์ •๋œ๋‹ค. Compression Resistance์— ๋”ฐ๋ผ ๋ทฐ๊ฐ€ ์ถ•์†Œ๋˜๊ณ , Content Hugging์— ๋”ฐ๋ผ ๋ทฐ๊ฐ€ ๋Š˜์–ด๋‚œ๋‹ค. ๋ชจํ˜ธํ•œ ๋ถ€๋ถ„์ด ์žˆ์œผ๋ฉด ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์กฐ์ •ํ•œ๋‹ค.

→ CHCR์— ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ...

 

๊ฐ ๋ทฐ์— CHCR์„ ์ฃผ์ง€ ์•Š๊ณ , distribution.fill์„ ํ•˜๊ฒŒ ๋˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

์ œ์•ฝ ์‚ฌํ•ญ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋œฌ๋‹ค. ์ด๊ฒŒ ์™œ ๋œจ๋ƒ๋ฉด, ๊ฐ ๋ทฐ๋งˆ๋‹ค ๋†’์ด(ํ˜น์€ ๋„“์ด)๊ฐ€ ์—†์–ด์„œ ๋ˆ„๊ฐ€ ๋Š˜์–ด๋‚˜์•ผํ•  ์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ˆ„๊ฐ€ ๋Š˜์–ด๋‚˜์•ผ ํ•  ์ง€ ์•Œ๊ณ ์žˆ๋‹ค๋ฉด ์ด๋Ÿฐ ์˜ค๋ฅ˜๋Š” ๋‹น์—ฐํžˆ ๋œจ์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์„ธ ๊ฐœ์˜ ๋ทฐ ์ค‘์— ๋‘ ๊ฐœ์˜ ๋ทฐ์— ๋†’์ด๋ฅผ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋‹น์—ฐํžˆ ์œ„์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋‘ ๊ฐœ์˜ ๋ทฐ์— ๋†’์ด๋ฅผ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ณต๊ฐ„์ด ๋‚จ๋Š”๋‹ค๋ฉด ๋†’์ด๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์€ ๋ทฐ๋ฅผ ๋Š˜๋ฆฌ๋ฉด ๋œ๋‹ค๋Š” ๊ฑธ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

fillEquality

๋ง ๊ทธ๋Œ€๋กœ ๋™์ผํ•œ ๋น„์œจ๋กœ ํฌ๊ธฐ๋กœ ์ฑ„์šด๋‹ค! axis์— ๋‚˜์™€์žˆ๋Š” ์‚ฌ์ง„์˜ ๊ตฌ์„ฑ์ด fillEquality ์˜€๋‹ค.

fillProportionally

์Šคํƒ ๋ทฐ์˜ ์ถ•์„ ๋”ฐ๋ผ ๊ณ ์œ  ์ฝ˜ํ…์ธ  ํฌ๊ธฐ์— ๋”ฐ๋ผ ๋น„๋ก€ํ•ด์„œ ํฌ๊ธฐ๊ฐ€ ์กฐ์ •๋œ๋‹ค.

๊ณต์‹ ๋ฌธ์„œ์—๋Š” ๋ถ€์—ฐ ์„ค๋ช…์ด ์—†์–ด์„œ ์ดํ•ด๊ฐ€ ์ž˜ ์•ˆ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. fillProportionally๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋ ค๋ฉด ๋ทฐ๊ฐ€ ๊ณ ์œ ํ•œ ์ฝ˜ํ…์ธ  ํฌ๊ธฐ(intrinsicContentSize)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ Button, Label, Slider ๋“ฑ์ด ๊ฐ–๊ณ  ์žˆ๋‹ค.

์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž. ๊ณ ์œ ํ•œ ์ฝ˜ํ…์ธ  ํฌ๊ธฐ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” UILabel๋ฅผ ๋‘ ๊ฐœ ๋ฐฐ์น˜ํ•ด๋ณด๋ฉด, ๋™๋“ฑํ•œ ๋น„์œจ๋กœ ํฌ๊ธฐ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ ์™ผ์ชฝ์˜ ํ…์ŠคํŠธ๋ฅผ ๋” ๊ธธ๊ฒŒ ๋ฐ”๊ฟ”๋ณด์ž. ํ…์ŠคํŠธ๊ฐ€ ๊ธธ์–ด์ง€๋ฉด์„œ ์Šคํƒ๋ทฐ ๋‚ด์—์„œ ๋” ๋งŽ์€ ๋„ˆ๋น„๋ฅผ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ดˆ๋ก์ƒ‰ ๋ทฐ๋„ ๋” ๊ธธ๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ๋ฏธ์„ธํ•˜๊ฒŒ ๋” ๋งŽ์€ ๋น„์œจ๋กœ ์ปค์ง„ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๊ณ , ๋‚˜๋จธ์ง€ ํ…์ŠคํŠธ๋Š” ...์œผ๋กœ ์ฒ˜๋ฆฌ๋œ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

equalSpacing

์Šคํƒ ๋ทฐ์˜ ์ถ•์„ ๋”ฐ๋ผ ๊ท ์ผํ•œ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ทฐ๋ฅผ ๋ฐฐ์น˜ํ•œ๋‹ค. ์ •๋ ฌ๋œ ๋ทฐ๊ฐ€ ์Šคํƒ ๋ทฐ์— ๋งž์ง€ ์•Š์œผ๋ฉด Compression Resistance์— ๋”ฐ๋ผ ๋ทฐ๊ฐ€ ์ถ•์†Œ๋œ๋‹ค.

UIStackView.spacing์˜ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ทฐ๋ฅผ ๋ฐฐ์น˜ํ•œ๋‹ค. spacing ๊ฐ’์ด ํฌ๋ฉด ์–ด๋–ค ๋ทฐ๊ฐ€ ์ž‘์•„์ ธ์•ผํ•  ์ง€ ์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

equalCentering

์Šคํƒ ๋ทฐ์˜ spacing ๊ฐ’์„ ๊ฐ„๊ฒฉ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์Šคํƒ ๋ทฐ์˜ ์ถ•์„ ๋”ฐ๋ผ ์ค‘์•™์—์„œ ์ค‘์•™๊นŒ์ง€์˜ ๊ฐ„๊ฒฉ์ด ๊ฐ™๋„๋ก ๋ฐฐ์น˜ํ•œ๋‹ค. ์ •๋ ฌ๋œ ๋ทฐ๊ฐ€ ์Šคํƒ ๋ทฐ์— ๋งž์ง€ ์•Š์œผ๋ฉด Compression Resistance์— ๋”ฐ๋ผ ๋ทฐ๊ฐ€ ์ถ•์†Œ๋œ๋‹ค.

๋ทฐ์˜ ์ค‘์•™ ์ถ•์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ„๊ฒฉ์„ ์œ ์ง€ํ•˜๋Š”๋ฐ, ๋ฌธ์žฅ๋งŒ ๋ด์„  ๊ฐ์ด ์ž˜ ์•ˆ ์žกํžŒ๋‹ค. ๊ทธ๋ฆผ์œผ๋กœ ๋ณด๋Š” ๊ฒŒ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.

alignment

์Šคํƒ ๋ทฐ์˜ ์ถ•์— ์ˆ˜์ง์ธ ๋ทฐ์˜ ๋ ˆ์ด์•„์›ƒ์„ ์ •์˜ํ•œ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ fill ์ด๋‹ค.

alginment๋Š” Axis์— ๋”ฐ๋ผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์ด ๋‹ฌ๋ผ์ง„๋‹ค.

Vertical

  • Fill
    • ๋ทฐ์˜ ํฌ๊ธฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ ๋„“์ด ์ „์ฒด๋งŒํผ ์ฑ„์šด๋‹ค.
  • Leading
    • ๋ทฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ Leading์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค. (์™ผ์ชฝ ์ •๋ ฌ X)
  • Center
    • ๋ทฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ ๊ฐ€์šด๋ฐ๋กœ ์ •๋ ฌํ•œ๋‹ค.
  • Trailing
    • ๋ทฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ Trailing์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค. (์˜ค๋ฅธ์ชฝ ์ •๋ ฌ X)

Horizontal

Vertical ์˜ˆ์ œ์™€ ๋‹ฌ๋ฆฌ ๊ฐ€์šด๋ฐ Label๋งŒ ์—ฌ๋Ÿฌ ์ค„๋กœ ์ž‘์„ฑํ–ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑํ•ด์•ผ ์ฐจ์ด๊ฐ€ ๋ˆˆ์— ๋ˆ๋‹ค.

  • Fill
    • ๋ทฐ์˜ ํฌ๊ธฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ ๋†’์ด๋งŒํผ ์ฑ„์šด๋‹ค.
  • Top
    • ๋ทฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ ์ƒ๋‹จ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.
  • Center
    • ๋ทฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ ๊ฐ€์šด๋ฐ๋กœ ์ •๋ ฌํ•œ๋‹ค.
  • Bottom
    • ๋ทฐ๋ฅผ ์Šคํƒ ๋ทฐ์˜ ํ•˜๋‹จ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.
  • First Baseline (only Horizontal)
    • ๋ทฐ๋ฅผ first Baseline์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.
  • Last Baseline (only Horizontal)
    • ๋ทฐ๋ฅผ last Baseline์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.

First Baseline๊ณผ Last Baseline์€ ์‚ฌ์ง„๋งŒ ๋ด์„œ๋Š” Top, Bottom๊ณผ ๋น„์Šทํ•ด๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋ก  ์ด๋ ‡๋‹ค.

spacing

์ธ์ ‘ํ•œ ๋ทฐ ์‚ฌ์ด์˜ ๊ณต๊ฐ„์˜ ํฌ๊ธฐ๋ฅผ ์ •์˜ํ•œ๋‹ค.

equalSpacing์ด๋‚˜ equalCentering์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ„๊ฒฉ์˜ ๊ฐ’์ด๋‹ค.

์ฐธ๊ณ  ์ž๋ฃŒ

  •  
๋ฐ˜์‘ํ˜•