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ํ์ฌ ์ฌ์ฉ๋ ๊ฐ๋ฅํ๋ค.
ํ์ง๋ง, ์ง์ ํธ์ถํ๋ ๊ฒ์ ๊ธ์ง๋์ด ์๋ค. ์ด๋ป๊ฒ ๋ณด๋ฉด ์ด ์์น์ ๋น์ฐํ๋ค.
- ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ๊ฒ์ Update Cycle์ ์ฒ๋ฆฌํด์ผ ํ๋ค.
- ์ฌ๊ท ํธ์ถ์ด๊ธฐ ๋๋ฌธ์ ๋ถํ๊ฐ ํฌ๊ธฐ ๋๋ฌธ์ 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
ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ค์ ๊ทธ๋ฆฐ๋ค.
์์ ๊ฐ์ด ์ฒ๋ฆฌํ์ฌ ๋ณด์ฌ์ง๋ ๋ฐฉ์์ ๋ฐ๊ฟ ์ ์๋ค. updateCycle๋ง๋ค ๋ณ๊ฒฝ๋ ๊ฐ์ ๋ฐ์ํ์ฌ ๊ทธ๋ฆด ์ ์๋ค.
Constraints
AutoLayout์์ ๋์ค๋ ๊ฐ๋ ์ด๋ค. ์์์ ์์๋ณธ Layout, Display๋ ๊ฒฐ๊ตญ ์ด๋ ํ ์ ์ฝ ์ฌํญ์ด ๋ณ๊ฒฝ๋์์ ๋, ์ด๋ป๊ฒ ์ ์ฉํ์ฌ ์์น์ ํฌ๊ธฐ์ ๋ณํ๋ฅผ ํ๋ฉด์ ์ ์ฉํ๊ณ , ํ๋ฉด ์์์ ๊ฐ์ ์์๋ค(์ ๋ฑ)์ ๋ณด์ฌ์ค ์ง์ ๋ํ ๊ฒ๋ค์ด์๋ค.
์์๋ณด์ง ์์ ๊ฒ์ ์ด Layout๊ณผ Display๊ฐ ์ ์ฉ๋๊ธฐ ์ด์ ์, ์ ์ฝ์ฌํญ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ์ด๋ค ๋ฐฉ์์ผ๋ก ์ด๋ฃจ์ด์ง๋๋์ด๋ค. ํด๋น ๋ด์ฉ์ ์ดํดํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ผ๋ก ํ๋ฉด์ด ์ ๋ฐ์ดํธ ๋๋ค๋ ๊ฒ์ ์ดํดํ ์ ์๋ค.
- Constraint
- Layout
- 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์ด๋ค.