iOS ํ™”๋ฉด ์—…๋ฐ์ดํŠธ๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋Š” ๊ฑธ๊นŒ? draw, layoutIfNeeded, setNeedsLayout ๋“ฑ. ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ€๋Š” ๊ฒƒ๋“ค์ด ๋„ˆ๋ฌด ๋งŽ์•˜๋‹ค. ์˜ค๋Š˜ ํ•œ๋ฒˆ ๋ถ€์…”๋ณด์ž!

Main Run Loop

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋“ค์„ ์ดํ•ดํ•˜๊ธฐ ์ „์—, View์˜ Layout์ด ์–ด๋–ค ์‹์œผ๋กœ ๊ทธ๋ ค์ง€๋Š”์ง€์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ํ•ต์‹ฌ์€ Run Loop์ด๋‹ค.

iOS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ main run loop๋Š” User์˜ ๋ชจ๋“  input event๋ฅผ ๋ฐ›๊ณ  ์ ์ ˆํ•œ ์‘๋‹ต์„ ํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•œ๋‹ค. ๋ชจ๋“  interaction์€ event queue๋ฅผ ๊ฑฐ์ณ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์ „๋‹ฌ๋œ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์˜ UIApplication ๊ฐ์ฒด๋Š” event queue์—์„œ event๋ฅผ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด๊ณ  ํ•ด์„ํ•˜์—ฌ ํ•˜์œ„ ๊ฐ์ฒด๋กœ ์ „๋”ธํ•œ๋‹ค.

์‹ค์ œ๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ ๋Š” ์ฝ”๋“œ๋Š” Core Object ์•ˆ์— ์žˆ๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•œ ๋’ค, ์ œ์–ด๊ถŒ์ด main run loop๋กœ ๋„˜์–ด๊ฐ„๋‹ค. ์ดํ›„ Update Cycle์ด ์‹คํ–‰๋˜์–ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ์—์„œ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋ฐ˜์˜ํ•œ๋‹ค. ์ฆ‰ View๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  ๋‹ค์‹œ ๊ทธ๋ฆฐ๋‹ค.

Update Cycle

Update Cycle์ด๋ž€, event๋ฅผ ๋„˜๊ธฐ๊ณ  ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ๋‹ค์‹œ main run loop๋กœ ๋Œ์•„๊ฐ„ ์‹œ์ ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

์ด ์‹œ์ ์—, ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ณ€๊ฒฝํ•˜๋ผ๋Š” ์ฝ”๋“œ๊ฐ€ ์‹ค์งˆ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์–ด ๊ทธ๋ ค์ง€๊ฒŒ ๋œ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์€ ๋‚ด ์ฝ”๋“œ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋Š” ์‹œ์ ๊ณผ, ์‹ค์งˆ์ ์œผ๋กœ ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๋Š” ์‹œ์ ์˜ ์ฐจ์ด๊ฐ€ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด ์ ์„ ์ธ์ง€ํ•˜์—ฌ์•ผ ์•„๋ž˜์˜ ๋‚ด์šฉ๋“ค์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ ์ด Update Cycle๊นŒ์ง€ ์ฒ˜๋ฆฌ๋˜์–ด ๋‹ค์‹œ ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•œ ์‹œ๊ฐ„์€ iOS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋Š” ์ดˆ๋‹น ํ”„๋ ˆ์ž„ (fps) ๋ฅผ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ํ˜„์žฌ ์ตœ๋Œ€ ์ดˆ๋‹น ํ”„๋ ˆ์ž„์€ 120fps (pro ๊ธฐ์ค€ - 22.03.07) ์ด๋ฏ€๋กœ ์ตœ๋Œ€ 1/120์ดˆ ์•ˆ์— ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๋ง์ด๋‹ค. ์œ„์˜ ์‚ฌ์ง„์˜ ๊ฒฝ์šฐ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” iphone 12 ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ–ˆ๋‹ค.

Layout

UIView์—์„œ Layout์€ ํ™”๋ฉด์—์„œ UIView์˜ ํฌ๊ธฐ์™€ ์œ„์น˜๋ฅผ ๋งํ•œ๋‹ค. ์ƒ๋Œ€์ขŒํ‘œ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ถ€๋ชจ View์— ๋Œ€ํ•ด์„œ ์–ด๋””์— ์œ„์น˜ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ (point), ํฌ๊ธฐ๋Š” ์–ผ๋งˆ์ธ์ง€ (size)๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์ด layout์ด๋‹ค.

layoutSubviews()

์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“œ๋Š” application์˜ ํ™”๋ฉด ๊ตฌ์„ฑ์€ Subview๋“ค์„ ์˜ฌ๋ฆฌ๋ฉด์„œ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ƒ์œ„ View์— ์˜์กด์„ฑ์ด ์žˆ๋Š” ๋งŒํผ, ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒ์œ„ ๋ทฐ๋ถ€ํ„ฐ ํ•˜์œ„๋ทฐ๋กœ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ์•ผ ์›ํ•˜๋Š” ํ™”๋ฉด์ด ํ‘œ์‹œ๋  ๊ฒƒ์ด๋‹ค.

์ด๋ ‡๊ฒŒ View์™€ ์ž์‹ View๋“ค์˜ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ์žฌ์กฐ์ •ํ•˜๊ธฐ ์œ„ํ•œ method๊ฐ€ layoutSubviews() ์ด๋‹ค. ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€ํ•˜๊ฐ€ ํฌ๋‹ค. ํ•˜์œ„ ๋ทฐ์—์„œ overrideํ•˜์—ฌ ์‚ฌ์šฉ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ•˜์ง€๋งŒ, ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ๊ธˆ์ง€๋˜์–ด ์žˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋ณด๋ฉด ์ด ์›์น™์€ ๋‹น์—ฐํ•˜๋‹ค.

  1. ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์€ Update Cycle์‹œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.
  2. ์žฌ๊ท€ ํ˜ธ์ถœ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€ํ•˜๊ฐ€ ํฌ๊ธฐ ๋•Œ๋ฌธ์— System์— ๋งก๊ธด๋‹ค.

์œ„์˜ ์ด์œ  ๋•Œ๋ฌธ์— ๊ธˆ์ง€๋˜์–ด ์žˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๊ฐœ๋ฐœ์ž๋Š” ์ž๊ธฐ๊ฐ€ ์›ํ•˜๋Š” ์‹œ์ ์— ํ™”๋ฉด์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์ด๋Ÿฐ ๋ถ€๋ถ„์„ ์œ„ํ•ด apple์€ ์—ฌ๋Ÿฌ method๋“ค์„ ๋งŒ๋“ค์–ด๋‘์—ˆ๋‹ค.

viewDidLayoutSubviews

UIViewController์—์„œ ๋ณ€ํ™”๋œ ํ™”๋ฉด์— ๋”ฐ๋ผ ์–ด๋–ค ๋กœ์ง์„ ์งœ๊ณ  ์‹ถ๋‹ค๋ฉด, viewDidLayoutSubviews์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์œ„ View๊นŒ์ง€ ๋ชจ๋‘ layoutSubviews๊ฐ€ ์™„๋ฃŒ๋œ ์‹œ์ ์— ํ•ด๋‹น callback์ด ํ˜ธ์ถœ๋œ๋‹ค. viewDidLoad ํ˜น์€ viewDidAppear์—์„œ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ, ๋ณ€๊ฒฝ๋œ ํ™”๋ฉด์ด ์ ์šฉ๋˜์ง€ ์•Š์€ ์‹œ์ ์— ๋กœ์ง์ด ์‹คํ–‰๋˜์–ด ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฐ๊ณผ๊ฐ€ ์ดˆ๋ž˜๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.

Automatic refresh triggers

๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตณ์ด ํ˜ธ์ถœํ•ด์ฃผ์ง€ ์•Š์•„๋„ ํ•ด๋‹น View๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๊ณ  ์ฒดํฌ๋˜๋Š” ์ด๋ฒคํŠธ๋“ค์ด๋‹ค. ์ž๋™์ ์œผ๋กœ layoutSubviews๊ฐ€ ๋‹ค์Œ updateCycle์— ํ˜ธ์ถœ๋œ๋‹ค.

  • View Resizing
  • Subview ์ถ”๊ฐ€
  • UIScrollView ์Šคํฌ๋กค์‹œ, UIScrollView, ๊ทธ๋ฆฌ๊ณ  ๋ถ€๋ชจ๋ทฐ์— layoutsubviews๊ฐ€ ํ˜ธ์ถœ๋จ
  • Device์˜ ํšŒ์ „
  • View์˜ Constraint ๋ณ€๊ฒฝ

setNeedsLayout()

๋‹ค์Œ UpdateCycle์—์„œ ํ•ด๋‹น View์—์„œ layoutSubviews๋ฅผ ํ˜ธ์ถœํ•ด๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค. ์œ„์˜ Automatic refresh trigger๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋‹ค์Œ update cycle์—์„œ ๋ฐ˜์˜ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

layoutIfNeeded()

setNeedsLayout๊ณผ ๋‹ฌ๋ฆฌ, layoutIfNeeded๋Š” ํ˜ธ์ถœ ์ฆ‰์‹œ layoutSubviews๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, ๋งŒ์•ฝ View๊ฐ€ ์žฌ์กฐ์ •๋˜์–ด์•ผ ํ•˜๋Š” ์ด์œ ๊ฐ€ ์—†๋‹ค๋ฉด layoutSubviews๋Š” ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ ‡๊ธฐ์— ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์ด layoutIfNeeded๋กœ ์ง€์–ด์ง„ ๊ฒƒ.

์ง€๊ธˆ๊นŒ์ง€์˜ ๊ธ€์„ ์ฝ์—ˆ๋‹ค๋ฉด, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์ƒ๋Œ€์ ์œผ๋กœ ์‹ ์ค‘ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๊ตณ์ด ๋น ๋ฅด๊ฒŒ ์—…๋ฐ์ดํŠธํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด setNeedsLayout์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์ ์€ ๋ถ€ํ•˜๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค ๊ฒฝ์šฐ์— ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ? ๋ฐ”๋กœ, ์• ๋‹ˆ๋ฉ”์ด์…˜์ด๋‹ค. Constraint๋ฅผ ์ ์šฉํ•œ ์ƒํƒœ๋กœ ๊ทธ๋ƒฅ setNeedsLayout์„ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ, 60fps(ํ˜น์€ 120fps)์— ๋Œ€์‘๋˜์–ด ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค. ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ๊ฒฝ์šฐ ๋ณด๋‹ค ๋ถ€๋“œ๋Ÿฌ์šด ํ™”๋ฉด ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ถ”๊ฐ€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ”๋กœ๋ฐ”๋กœ ์ด๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ์ข‹์€ ๊ฒฝํ—˜์„ ์„ ์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

Display

Layout์ด View์˜ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค๋ฉด, Display๋Š” ๋ทฐ์˜ ์†์„ฑ์ค‘ ํฌ๊ธฐ, ์œ„์น˜, ์ž์‹ View์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ์™ธํ•œ ๊ฒƒ๋“ค์„ ๋งํ•œ๋‹ค.

  • Color
  • Text
  • Image
  • Core Graphics

Display ์—ญ์‹œ ์‹œ์Šคํ…œ์˜ ํ๋ฆ„์—์„œ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋„๋ก ์˜ˆ์•ฝ ๊ฑฐ๋Š” ๋ฐฉ์‹๊ณผ ๋ช…์‹œ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋“ค์ด ์žˆ๋‹ค.

draw(_:)

Layout์—์„œ layoutSubviews์™€ ๊ฐ™์€ ์—ญํ• ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. ์ฆ‰, ํ•˜์œ„ View์˜ draw๋Š” ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ.

ํ•ด๋‹น ํ•จ์ˆ˜ ์•ˆ์—์„œ ํ™”๋ฉด์— ๋ณด์ด๋Š” ์†์„ฑ๋“ค์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. layoutSubviews์™€ ๊ฐ™์ด ์ง์ ‘ ํ˜ธ์ถœ์€ ์ข‹์ง€ ์•Š๋‹ค.

setNeedsDisplay()

setNeedsLayout๊ณผ ์œ ์‚ฌํ•˜๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด๋‘๋ฉด, ๋‹ค์Œ UpdateCycle์—์„œ draw ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋‹ค์‹œ ๊ทธ๋ฆฐ๋‹ค.

class MyView: UIView {
    var numberOfPoints = 0 {
        didSet {
            setNeedsDisplay()
        }
    }
 
    override func draw(_ rect: CGRect) {
        switch numberOfPoints {
        case 0:
            return
        case 1:
            drawPoint(rect)
        case 2:
            drawLine(rect)
        case 3:
            drawTriangle(rect)
        case 4:
            drawRectangle(rect)
        case 5:
            drawPentagon(rect)
        default:
            drawEllipse(rect)
        }
    }
}

์œ„์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ณด์—ฌ์ง€๋Š” ๋ฐฉ์‹์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. updateCycle๋งˆ๋‹ค ๋ณ€๊ฒฝ๋œ ๊ฐ’์„ ๋ฐ˜์˜ํ•˜์—ฌ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

Constraints

AutoLayout์—์„œ ๋‚˜์˜ค๋Š” ๊ฐœ๋…์ด๋‹ค. ์œ„์—์„œ ์•Œ์•„๋ณธ Layout, Display๋Š” ๊ฒฐ๊ตญ ์–ด๋– ํ•œ ์ œ์•ฝ ์‚ฌํ•ญ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ, ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜์—ฌ ์œ„์น˜์™€ ํฌ๊ธฐ์˜ ๋ณ€ํ™”๋ฅผ ํ™”๋ฉด์— ์ ์šฉํ•˜๊ณ , ํ™”๋ฉด ์š”์†Œ์˜ ๊ฐ€์‹œ ์š”์†Œ๋“ค(์ƒ‰ ๋“ฑ)์„ ๋ณด์—ฌ์ค„ ์ง€์— ๋Œ€ํ•œ ๊ฒƒ๋“ค์ด์—ˆ๋‹ค.

์•Œ์•„๋ณด์ง€ ์•Š์€ ๊ฒƒ์€ ์ด Layout๊ณผ Display๊ฐ€ ์ ์šฉ๋˜๊ธฐ ์ด์ „์—, ์ œ์•ฝ์‚ฌํ•ญ์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋Š๋ƒ์ด๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์„ ์ดํ•ดํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ๋ฆ„์œผ๋กœ ํ™”๋ฉด์ด ์—…๋ฐ์ดํŠธ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. Constraint
  2. Layout
  3. Display

๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋กœ Constraint์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋ คํ•œ๋‹ค.

updateConstraints

layout ๋‹จ๊ณ„์—์„œ์˜ layoutSubviews๋‚˜, Display๋‹จ๊ณ„์—์„œ draw์™€ ๊ฐ™์ด updateConstraints๋Š” overrideํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ , ์ง์ ‘ ํ˜ธ์ถœ์€ ๊ธˆ์ง€๋˜์–ด ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๊ฒฐ๊ตญ, updateCycle์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๊ฒƒ์„ ์˜ˆ์ƒํ•˜๊ณ  overrideํ•˜์—ฌ ๊ตฌํ˜„์‚ฌํ•ญ์„ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค๋Š” ์†Œ๋ฆฌ์ด๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ๋ณดํ†ต ๋™์ ์œผ๋กœ constraint๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ์œ„์˜ setNeedsDisplay์™€ ๊ฐ™์ด ํŠน์ • ์ƒํƒœ๊ฐ’์ด ์žˆ๊ณ , updateCycle๋งˆ๋‹ค ์ด๋ฅผ ์ฒดํฌํ•˜๊ณ  ๋‹ค๋ฅธ constraint๋ฅผ ์ ์šฉํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

๋ณดํ†ต ์ •์ ์ธ constraint๋Š” interface builder๋‚˜ viewDidLoad์—์„œ ์ •์˜ํ•˜๊ณ  ๋“ค์–ด๊ฐ”์—ˆ๋‹ค. ๋งŒ์•ฝ ๋™์ ์ธ constraint๋ฅผ ์ •์˜ํ•ด์•ผํ•œ๋‹ค๋ฉด IBOutlet์œผ๋กœ ๋ณ€์ˆ˜๋ฅผ ๋“ค๊ณ ์žˆ๊ฑฐ๋‚˜, ๊ทธ๋ƒฅ constraint๋ฅผ ๋ณ€์ˆ˜๋กœ ๋“ค๊ณ  updateConstraint์— ์ ์–ด๋‘๋ฉด system์ด ํ˜ธ์ถœํ•ด ์ค„ ๊ฒƒ์ด๋‹ค.

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ์‹œ์Šคํ…œ์—์„œ ํ˜ธ์ถœํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ผ๋Š” ์‚ฌ์‹ค์ด ์ค‘์š”ํ•˜๋‹ค.

setNeedsUpdateConstraints

๋‹ค์Œ updateCycle์—์„œ Constraint๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋„๋ก ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค. setNeedsLayout์ด๋‚˜ setNeedsDisplay์™€ ๋น„์Šทํ•˜๋‹ค.

updateConstraintsIfNeeded()

updateConstraints์˜ ๊ฒฝ์šฐ๋Š” updateCycle์— ๋งž์ถฐ์„œ ๋™์ž‘ํ•˜๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ์˜€๋‹ค. layoutIfNeeded์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐ”๋กœ constraint๋ฅผ ์ ์šฉ, ์ฆ‰ updateContraint๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด Ststem์€ Constraint Update Flag๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค. ์ด Flag๋Š” setNeedsUpdateConstraints๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฝ์šฐ ์—ญ์‹œ ์„ค์ •๋œ๋‹ค. ๊ฒฐ๊ตญ ์ƒ๊ธฐ ์ ์€ ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋“ค์€ Flag๋ฅผ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” ํ–‰์œ„์ด๋ฉฐ, ์ด๋ฅผ ์ฝ๊ณ  ์‹œ์Šคํ…œ์ด ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น Flag๋Š” invalidIntrinsicContentSize๋ฅผ ํ†ตํ•ด ์„ค์ •๋  ์ˆ˜๋„ ์žˆ๋‹ค.

๋งŒ์•ฝ Constraint๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด updateConstraints ํ•จ์ˆ˜๋ฅผ ์ฆ‰์‹œ ํ˜ธ์ถœํ•œ๋‹ค.

invalidateIntrinsicContenstSize

AutoLayout์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ช‡๋ช‡ View๋“ค์€ intrinsicContentSize ์†์„ฑ์„ ๊ฐ–๋Š”๋‹ค. ์ด๋Š” View๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” Content์˜ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์ด๋‹ค.

๋ณดํ†ต view์˜ Contraint๋กœ ๊ฒฐ์ •๋˜์ง€๋งŒ, overrideํ•˜์—ฌ ํŠน์ • view์˜ content size๋ฅผ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์„ค์ •๋œ view์˜ ๊ฒฝ์šฐ, invalidIntrinsicContentSize๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ View๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” intrinsicContentSize๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•จ์„ ์•Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ Flag๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด ๋‹ค์Œ Update Cycle์—์„œ ๋ฐ˜์˜๋œ๋‹ค.

์ •๋ฆฌ

์œ„์˜ ๋‚ด์šฉ์„ ๋ชจ๋‘ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ์ฒ˜์Œ ๋ณผ ๋•Œ๋Š” ๋ญ”์ง€ ์ž˜ ๋ชฐ๋ž๋Š”๋ฐ ์ด์ œ์ข€ ์ดํ•ด๊ฐ€ ๋œ ๊ฒƒ ๊ฐ™๋‹ค!

๋‹ค์Œ์€ ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ์ด ์–ด๋–ค ์‹์œผ๋กœ ์‹œ์Šคํ…œ์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€์— ๋Œ€ํ•œ Flow Chart์ด๋‹ค.

Reference