<h1><center> setNeedsLayout vs layoutIfNeeded </center></h1>
###### tags: `๐ป TIL`
###### date: `2024-01-30T15:12:33.284Z`
> [color=#724cd1][name=๋ฐ๋ฆญ]
> [Corn ๋ธ๋ก๊ทธ - setNeedsLayout vs layoutIfNeeded](https://baked-corn.tistory.com/105)
> [Demystifying iOS Layout](https://tech.gc.com/demystifying-ios-layout/)
> [layoutSubviews() - Apple Documentation](https://developer.apple.com/documentation/uikit/uiview/1622482-layoutsubviews)
> [setNeedsLayout() - Apple Documentation](https://developer.apple.com/documentation/uikit/uiview/1622601-setneedslayout)
> [layoutIfNeeded() - Apple Documentation](https://developer.apple.com/documentation/uikit/uiview/1622507-layoutifneeded)
# ๊ฐ์
> ์ต๊ทผ์ ํ ํ๋ก์ ํธ์์ ์ ๋๋ฉ์ด์
์ ์ค ๋ ์ ๋๋ก ์์ง ๋ชปํ๊ณ setNeedsLayout์ ์ฌ์ฉํด์ ๋ทฐ๋ฅผ ์
๋ฐ์ดํธ ํด๋ณธ ์ ์ด ์๋ค. ๊ทธ ๋ ์ ๋๋ก ์์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ์ง๊ธ ํ์ตํ๊ณ ์ ํ๋ค.
์ผ๋จ ๋ ๊ฐ์ ๋ฉ์๋๋ฅผ ๋น๊ตํ๊ธฐ์ ์์ `main run loop` ๊ฐ๋
์ ๋ํด ์์์ผ ํ๋ค. [Run Loop](https://hackmd.io/tev-lJIOTN6IMcRqYT4qyw)๋ ์ฌ๊ธฐ์ ํ์ธํ์.
## Main Run Loop
Main Thread์์๋ ์ฑ ์์ ๊ณผ์ (UIApplication) ์ค์ ์๋์ผ๋ก Run Loop๊ฐ ์คํ๋๋ค. Main Run Loop๋ ํฐ์น ์ด๋ฒคํธ, ์์น ๋ณํ, ๋๋ฐ์ด์ค ํ์ , ํ์ด๋จธ ๋ฑ์ ์ด๋ฒคํธ๋ค์ ์ฒ๋ฆฌํ๊ฒ ๋๋ค. ์ด๋ฐ ์ฒ๋ฆฌ ๊ณผ์ ์ ๊ฐ ์ด๋ฒคํธ์ ์ ์ ํ ํธ๋ค๋ฌ๋ฅผ ์ฐพ์ ์ฒ๋ฆฌ ๊ถํ์ ์์ํด์ ์งํํ๊ฒ ๋๋ค.
Main Run Loop์์ ์ด๋ฒคํธ๊ฐ ์ฒ๋ฆฌ๋๋ ๊ณผ์ ์์ ๋ฒํผ์ ๋๋ฅด๊ฑฐ๋ ํฌ๊ธฐ, ์์น๊ฐ ์ด๋ํ๋ ์ ๋๋ฉ์ด์
์คํ์ผ๋ก position์ ๊ฐ์ ๋ฐ๊พธ๋ ํธ๋ค๋ฌ๊ฐ ์คํ๋ ๋๋ ์๋ค.
**ํ์ง๋ง** ์ด๋ฐ ๋ณํ๋ ์ฆ๊ฐ์ ์ผ๋ก ๋ฐ์๋๋ ๊ฒ์ด ์๋๋ค.
System์ layout or position์ด ๋ฐ๋๋ ๋ทฐ๋ฅผ ์ฒดํฌํ๋ค. ๋ทฐ๊ฐ ๊ฐฑ์ ๋๋ ์์ ์ ๋ชจ๋ ํธ๋ค๋ฌ๊ฐ ์ข
๋ฃ๋๊ณ Main Run Loop๋ก ๊ถํ์ด ๋๋์ ์ค๋ ์์ ์ธ Update Cycle์์ ๋๋ค.(Position, layout์ ๋ณํ๋ฅผ ์ ์ฉ)
**NOTE**
> Update Cycle: ๋ฐ์ํ ์ด๋ฒคํธ๋ค์ ๋ชจ๋ ์ฒ๋ฆฌํ๊ณ ๊ถํ์ด Main Run Loop๋ก ๋์์ค๊ฒ ๋๋ ์์

๋ค์ ๋งํด์, ๋ทฐ์ position or layoutd์ ๋ณํ๋ฅผ ๊ฐฑ์ ํ๋ ๊ฒ์ ์๊ฐ์ฐจ๊ฐ ์กด์ฌํ๋ค๋ ๊ฒ์ด๋ค.
์ฐ๋ฆฌ๊ฐ ๊ฐ๋ฐํ ๋๋ ์ด๋ฐ ์๊ฐ์ฐจ๋ฅผ ํญ์ ๊ณ ๋ คํด์ผ ํ๋ค.
## layoutSubviews()
> ์ด ๋ฉ์๋๊ฐ ์คํ๋๋ ์์ ์์ ํ์ ๋ทฐ๋ฅผ ๋ฐฐ์นํ๊ฒ ๋๋ค. ํธ์ถํ๋ฉด ํด๋น ๋ทฐ์ ๋ชจ๋ Subview๋ค์ด layoutSubviews๋ฅผ ์ฐ๋ฌ์ ํธ์ถํ๋ค. ์์คํ
์ ์ํด์ ๋ทฐ์ ๊ฐ์ด ์ฌ๊ณ์ฐ๋๋ ์์ ์ ์๋์ผ๋ก ํธ์ถ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๊ฐ ๋ฐ๋ก ํธ์ถํ ๊ฒฝ์ฐ ๋น์ฉ์ด ๋ง์ด ๋๋ ๋ฉ์๋์ด๋ค.
๊ฐ๋ฐ์๊ฐ ์ค์ ํ Contraints๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ๋ทฐ์ size, position์ ๊ฒฐ์ ํ๋ค.
์ด ๋ฉ์๋๋ ํ์์ ๋ฐ๋ผ ํ์ ๋ทฐ์ ๋ ์ด์์์ ๋ ์ ํํ๊ฒ ์กฐ์ ํ๊ธฐ ์ํด ํ์ํ ๊ฒฝ์ฐ ์๋ธํด๋์ค์์ overrideํ ์ ์๋ค.
์ด ๋ฉ์๋๋ฅผ overrideํด์ผํ๋ ์ด์ ๋ ํ์ ๋ทฐ์ autoresizing ๋ฐ constraint-based ๋์์ ์ ๊ณตํ์ง ์์ ๋์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ํ์ ๋ทฐ์ Frame ์ฌ๊ฐํ์ ์ง์ ์ค์ ํ ์๋ ์๋ค.
**ํ์ง๋ง**
์ด ๋ฉ์๋๋ฅผ ์ง์ ํธ์ถํด์๋ ์๋๋ค. ๋ ์ด์์์ ๊ฐ์ ์ ์ผ๋ก ์
๋ฐ์ดํธํ๋ ค๋ฉด drawing์ด ์
๋ฐ์ดํธ ๋๊ธฐ ์ ์ setNeedsLayout()๋ฅผ ํธ์ถํด์ผ ํ๋ค.
๋๋, ๋ทฐ์ ๋ ์ด์์์ ์ฆ์ ์
๋ฐ์ดํธํ๋ ค๋ฉด layoutIfNeeded()๋ฅผ ํธ์ถํ๋ผ.
**NOTE**
> UIViewController ๋ด์ ๋ทฐ๊ฐ ์ฌ๊ณ์ฐ๋์ด ๋ค์ ๊ทธ๋ ค์ง๋ ํ์๊ฐ ๋ฐ์ํ๋ ๊ณผ์ ์ layoutSubviews๋ฅผ ํธ์ถํ๊ณ ํ์ ๋ทฐ๊ฐ ๋ฐฐ์น๋๋ฉด ๊ทธ ๋ค์์ผ๋ก viewDidLayoutSubviews๊ฐ ํธ์ถ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๊ฐฑ์ ๋ View ๊ฐ์ ์์กดํ๋ ํ์๋ค์ ์ด ๋ฉ์๋์ ๋ช
์ํด์ผ ํ๋ค. <br>
EX) Layer ๊ฐ์ ์๋์ผ๋ก ์
๋ฐ์ดํธ๋์ง ์๋๋ค. ๊ทธ๋์ ์ํ ๋ทฐ์ Frame์ด ๋ณ๊ฒฝ๋๋ฉด, ์ด์ ๋์ํ์ฌ `viewDidLayoutSubviews` ์์์ ๋ ์ด์ด์ frame์ ์๋์ผ๋ก ์กฐ์ ํด์ผ ํ๋ค.
- View์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ๋
- Subview๋ฅผ ์ถ๊ฐํ ๋
- ์ฌ์ฉ์๊ฐ UIScrollView๋ฅผ ์คํฌ๋กคํ ๋
- ๋๋ฐ์ด์ค๋ฅผ ํ์ ์์ผฐ์ ๋ (Orientation)
- View์ AutoLayout ์ ์ฝ ์กฐ๊ฑด์ ๋ณ๊ฒฝ์์ผฐ์ ๋
์์ ์ธ๊ธ๋ ์์ ๋ค์ layoutSubviews๋ฅผ ์๋์ผ๋ก ํธ์ถํ๊ธฐ ์ํ update cycle์์์ ํน์ ์ง์ ๋ค์ ๋ํ๋ธ๋ค.
์๋๋ ์๋ ์์ฝ์ด ์๋ ์๋์ผ๋ก ์
๋ฐ์ดํธ ์ฃผ๊ธฐ๋ฅผ ์์ฝํ๋ ๋ฉ์๋๋ค์ด๋ค.
## setNeedsLayout()
> Receiver์ ๋ทฐ๋ฅผ ๋ฌดํจํํ๊ณ ๋ค์ update cycle๋์ ๋ ์ด์์์ ์
๋ฐ์ดํธ ํ๊ธฐ ์ํด ํธ๋ฆฌ๊ฑฐ ํ๋ ๊ฒ์ด๋ค.
ํ์ ๋ทฐ์ ๋ ์ด์์์ ์กฐ์ ํ๋ ค๋ฉด ์ด ๋ฉ์๋๋ฅผ Main Thread์์ ํธ์ถํด์ผ ํ๋ค. ์ด ๋ฉ์๋๋ ์์ฒญํ ๊ฒ์ ๊ธฐ๋กํ๊ณ ์ฆ์ ๋ฐํํ๋ค. ํน์ง์ผ๋ก๋ ์ฆ์ ๋ทฐ๋ฅผ ๊ฐฑ์ ํ์ง ์๊ณ ๋ค์ Update cycle์ ๊ธฐ๋ค๋ฆฌ๊ธฐ ๋๋ฌธ์ ์
๋ฐ์ดํธ๋๊ธฐ ์ ์ setNeedsLayout์ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ๋ทฐ์ ๋ ์ด์์์ ๋ฌดํจํํ ์ ์๋ค. ๋ํ, ์ด ๋์์ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ๋ ์ด์์์ ์
๋ฐ์ดํธ๋ฅผ ํ๋์ update cycle๋ก ํตํฉํ ์ ์์ผ๋ฏ๋ก ์ผ๋ฐ์ ์ผ๋ก ์ฑ๋ฅ์ ๋ ์ข๋ค.
## layoutIfNeeded()
> ๋ ์ด์์์ ์
๋ฐ์ดํธ๊ฐ ๋ณด๋ฅ ์ค์ธ ๊ฒฝ์ฐ, ํ์ ๋ทฐ๋ฅผ ์ฆ์ ๊ฐฑ์ ํ๋ค.
์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๋ทฐ์ ๋ ์ด์์์ ์ฆ์ ์
๋ฐ์ดํธํ ์ ์๋ค. Auto layout์ ์ฌ์ฉํ ๋, ๋ ์ด์์ ์์ง์ ์ ์ฝ ์กฐ๊ฑด์ ๋ณ๊ฒฝ ์ฌํญ์ ์ถฉ์กฑํ๊ธฐ ์ํด ํ์์ ๋ฐ๋ผ ๋ทฐ์ ์์น๋ฅผ ์
๋ฐ์ดํธ ํ๋ค. ๋ฉ์ธ์ง๋ฅผ ๋ฐ์ ๋ทฐ๋ฅผ ๋ฃจํธ ๋ทฐ๋ก ์ฌ์ฉํ์ฌ ๋ฃจํธ์์ ์์ํ๋ ๋ทฐ ํ์ ํธ๋ฆฌ๋ฅผ ๋ฐฐ์นํ๋ค. ๋ณด๋ฅ ์ค์ธ ๋ ์ด์์ ์
๋ฐ์ดํธ๊ฐ ์์ผ๋ฉด, ์ด ๋ฉ์๋๋ ๋ ์ด์์์ ์์ ํ๊ฑฐ๋ ๋ ์ด์์ ๊ด๋ จ ์ฝ๋ฐฑ์ ํธ์ถํ์ง ์๊ณ ์ข
๋ฃ๋๋ค.
## ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ
Main Run Loop์์ ํ View๊ฐ `setNeedsLayout`์ ํธ์ถํ๊ณ ๋ฐ๋ก ๋ค์์ `layoutIfNeeded`๋ฅผ ํธ์ถํ๋ค๋ฉด, `layoutIfNeeded`๋ ์ฆ์ View์ ๊ฐ์ ์ฌ๊ณ์ฐํ๊ณ ๋ทฐ์ ๋ฐ์ํ๊ฒ ๋๋ค. ์ด๋ก ์ธํด `setNeedsLayout`์ด ์์ฝํ `layoutSubviews` ๋ฉ์๋๋ ํด๋น update cycle์์ ๋ณ๊ฒฝ๋ ๊ฐ์ด ์์ด ํธ์ถ๋์ง ์๊ฒ ๋๋ค.
์ด๋ฐ ์๋ ๋ฐฉ์์ผ๋ก `layoutIfNeeded`๋ ์ฆ์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด์ผ ํ๋ ์ ๋๋ฉ์ด์
์์ ๋๋ฆฌ ์ฌ์ฉ๋๋ค. ๋ฐ๋ฉด์ `setNeedsLayout`์ ์ฌ์ฉํ๋ฉด ์ ๋๋ฉ์ด์
๋ธ๋ก์์ ๊ฐ์ด ์ฆ์ ๋ณ๊ฒฝ๋์ง ์๊ณ ๋์ค์ ์
๋ฐ์ดํธ ์ฃผ๊ธฐ์์ ๊ฐ์ด ๋ฐ์๋๋ฏ๋ก ๋ณ๊ฒฝ์ ์ด๋ฃจ์ด์ง์ง๋ง ์ ๋๋ฉ์ด์
ํจ๊ณผ๊ฐ ๋์ ๋์ง ์์ต๋๋ค.