-
[iOS] Safe Area ์ Layout Margins ์ด๋?iOS/๐ค App 2021. 8. 10. 15:47
์๋ ํ์ธ์๐ถ
์ด๋ฒ ์๊ฐ์๋ Safe Area ์ Layout Margins ์ ๋ํด์ ์์๋ณด๊ฒ ์ต๋๋ค.
์ด์ ๊น์ง๋ ์ ํํ๊ฒ ๋ชจ๋ฅด๊ณ ์ฌ์ฉํ๋ ๊ฐ๋ ๋ค์
์ด๋ฒ ๊ธฐํ์ ๊ณต๋ถํ๋ฉด์ ์ ๋๋ก ์์๋ณผ ์ ์๋ ์ข์ ๊ธฐํ์๋๋ฐ์.
๋๋ฌด ๋ฟ๋ฏํ ๋ง์์ ์ ๋๊ฒ ๊ธ์ ์ ์์ต๋๋ค.
๊ทธ๋ผ ์์ํ ๊ฒ์~!!!!๐ฅ๐ฅ๐ฅ
Layout Margins ์ ๊ฐ๋
๋ทฐ์ ์ญํ ์ค ํ๋๋ ์ปจํ ์ธ ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ ๋๋ค.
๋ทฐ ์์๋ ์ปจํ ์ธ ๊ฐ ์๋๋ฐ์.
์ด ์ปจํ ์ธ ์ ์์น๋ฅผ Layout Margins ์ ํตํด์ ์กฐ์ ํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ๋ค๋ฅธ ๋ทฐ์ ์ํด ์ปจํ ์ธ ๊ฐ ๊ฒน์น๋ ๊ฒ์ ๋ง์์ค ์ ์์ต๋๋ค.
Layout Margins ๋ ์ปจํ ์ธ ์ ๋ทฐ์ bounds ์ฌ์ด์ ์๊ฐ์ ์ธ ๋ฒํผ์ ๋๋ค.
๋ฒํผ๋ ์ฝ๊ฒ ์์ถฉ์ฌ ์ญํ ์ ํ๋ ๊ณต๊ฐ์ผ๋ก ์๊ฐํ๋ฉด ๋๋๋ฐ์.
ํน์ง์ ๋ทฐ ๋ฐ๊นฅ์ด ์๋ ์์ชฝ์ผ๋ก ๋์ด์ง๋ ์์ถฉ์ง์ญ์ด๋ผ๋ ๊ฒ์ด์์.
์ด ๋ฒํผ๋ฅผ ํตํด์ ๋ทฐ ๋ฐ๊นฅ์ ์ฝํ ์ธ ์ ๊ฒน์น๋ ์ผ์ ๋ฐฉ์งํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก ์น ๋ถ์ผ์์ ํจ๋ฉ์ด๋ผ๊ณ ๋ถ๋ฅด๋ ๋ถ๋ถ๊ณผ ์ ์ฌํ๋ต๋๋ค~!
Layout margin ์ ๊ฐ๊ฐ์ ๋ชจ์๋ฆฌ์ ํด๋นํ๋ inset ๊ฐ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ์ด 4๊ฐ ( top, bottom, leading, trailing ) ์ inset ๊ฐ์ ๊ฐ์ง๊ณ ์๋๋ฐ,
์ฌ๊ธฐ์ Inset ๊ฐ์ ๊ฐ ๋ชจ์๋ฆฌ์์ ๋ทฐ์ ์ค์ฌ ๋ฐฉํฅ์ผ๋ก ํฅํ๋ ์ ๋๋ผ๊ณ ์ดํดํ์๋ฉด ๋๊ฒ ์ต๋๋ค.
๋ค์ ๊ทธ๋ฆผ์ ์ ๋ด์ฉ์ ์ค๋ช ํ๊ณ ์์ต๋๋ค.
์ฝ๋๋ก ์ ๊ทผํ๋ Layout Margins
์ฝ๋์์๋ layoutMargins ์์ฑ์ผ๋ก ์ ๊ทผํ๊ฑฐ๋, ์๋ก ์ค์ ํด ์ค์ ์์ต๋๋ค.
UIEdgeInsets ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๋ฃ์ด์ฃผ๋ฉด ๋๋๋ฐ,
์ ๊ทธ๋ฆผ์ ์ดํดํํ๋ฉด ์ด๋ค ๋ ์ด์์ ๋ง์ง์ด ๊ทธ๋ ค์ง์ง ๋ฐ๋ก ์ดํด๊ฐ ๊ฐ๋ ๋ถ๋ถ์ด์ฃ ?
์ด๋ ๊ฒ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๋ค์ ๋ฃ์ด์ฃผ๋ฉด ๋ ์ด์์ ๋ง์ง์ด ์๋ก ์ค์ ๋ฉ๋๋ค.
๊ทธ๋ฐ๋ฐ ๋ฌธ์์์๋ leading, trailing ์ธ๋ฐ
์ ๋ฐ๋ก ์ ์ฌ์ง์์๋ left, right ๋ผ๋ argument label ์ ๊ฐ์ง๋ ์์ฑ์๊ฐ ์ ๊ณต๋์์๊น์.....?
๋ผ๊ณ ์๊ฐํ๋๋ฐ, ๋ฌธ์์ ์ด๋ฐ ์์ฑ๋ ์๋ค์...ใ ใ ใ ใ
iOS 11 ๋ถํฐ๋ directionalLayoutMargins ๋ฅผ ์ฌ์ฉํ๋ผ๊ณ ํฉ๋๋ค.
leading, trailing ์ ์ค๋ฅธ์ชฝ๋ถํฐ ์ฝ๋ ๋ฌธํ๊ถ์ ๊ณ ๋ คํด์ ๊ณ ์๋ ๋ฐฉํฅ ๊ฐ๋ ์ด์ฃ ??
๋ทฐ, ํนํ VC์ ๋ฃจํธ๋ทฐ์ธ ์ปจํ ํธ ๋ทฐ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก๋ ์ด๋ค ๋ง์ง ๊ฐ์ด ๋ค์ด์์๊น์?????????
์ด๊ฑด ์๋ Safe Area ๋ถ๋ถ์์ ๋ค๋ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
Interface Builder ์์ ๋ง๋ ์ ์๋ Layout Margins
๋ณธ๋ก ์ผ๋ก ๋์์์
Layout margins ์ 'margins' ๋ผ๋ ๋จ์ด๋ก Interface Builder ์์๋ ๋ง๋๋ณผ์ ์๋๋ฐ์
์์ฒ๋ผ Constrain to margins ์ต์ ์ ์ฒดํฌํ๋ค๋ฉด,
์ ์ฝ์ ๊ธฐ์ค์ด ๋๋ ๋ทฐ์ bounds ๊ฐ ์๋๋ผ
๋ทฐ์ margin ์ ๊ธฐ์ค์ผ๋ก ์ ์ฝ์ ์ก๊ฒ ๋ฉ๋๋ค.
์ง์ ํ๋ฒ ํด๋ณผ๊น์???
<๊ธฐ๋ณธ ์กฐ๊ฑด>
์ค๋ ์ง ๋ทฐ์ directionalLayoutMargins ์
leading, top, bottom, trailing ๊ฐ์ ๊ฐ๊ฐ 50์ฉ ๋ถ์ฌํด์คฌ์ด์!
์ด์ ์ค๋ ์ง๋ทฐ์ ํ์๋ทฐ๋ก ํผํ๋ทฐ๋ฅผ ์ถ๊ฐํ๊ณ , ์คํ ๋ ์ด์์์ ์ก์์ฃผ๊ฒ ์ต๋๋ค.
< Constaint to margins ์ฒดํฌ๋ฅผ ํด์ >
< Constaint to margins ์ฒดํฌ>
์ด๋ ๊ฒ ์ฐ๋ฆฌ๋ ์ง์ ๋ทฐ์ Layout Margins ๋ฅผ ์ค์ ํ ์ ์๊ฒ ๋์์ต๋๋ค!!
๋จ, ๋ฑ ํ๊ฐ์ง ๊ฒฝ์ฐ!!!!!!!! ์์ธ๊ฐ ์๋๋ฐ์.
๋ฐ๋ก View Controller ์ root view ์ ๋๋ค.
UIKit ์ root view ๊ฐ ์ง์ผ์ผํ๋ ์ต์ํ์ layout margins ๊ฐ์ ๊ฐ์ ํฉ๋๋ค.
~ ๋ง์ง ๊ฐ์ ์ต์ํ ์ด๋งํผ์ ๋ฃ์ด์ค์ผ ํ๋ค~ ๋ผ๋ ์๋ฏธ
์ปจํ ์ธ ๋ฅผ ๊ฐ๋ฆฌ์ง ์๊ณ ์ ๋๋ก ๋ณด์ฌ์ฃผ๊ธฐ ์ํด์ ์ธ๋ฐ์.
๊ทธ๋์ ๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์์๋ก root view ์ ๋ง์ง์ (0,0,0,0) ์ผ๋ก ์ค์ ํ๋ค๊ณ ํ๋๋ผ๋,
์ด๊ฒ์ด UIKit์ด ์ ํด ๋์ ์ต์๊ฐ๋ณด๋ค ์๋ค๋ฉด, ์ด ๊ฐ์ ๋ฌด์ํ๊ณ ์ต์๊ฐ์ผ๋ก ๋์ฒด์์ผ๋ฒ๋ฆฝ๋๋ค....
๊ทธ๋ฐ๋ฐ ๋ฌด์จ ์ด์ ๋๋ฌธ์ UIKit ์ด ๋ฃจํธ๋ทฐ์ ์ ๋ง์ง ๊ฐ์ (0,0,0,0) ๋ณด๋ค ํฐ ๊ฐ์ผ๋ก ์ต์ ๊ฐ์ ์ ํด๋์ ๊ฒ์ผ๊น์???
์ด๊ฒ์ด ๋ฐ๋ก ์ด์ด์ ๋งํ Safe Area ์ ๊ด๋ จ๋์ด์์ต๋๋ค.
Safe Area ์ ๊ฐ๋
SafeArea ๋ ํธ๋ํฐ์ ์ ์ฒด์ ์ธ UI๋ฅผ ํตํ์ด์ ์ปจํ ์ธ ๊ฐ ์ ๋๋ก ๋ณด์ผ์ ์๋ ๋ถ๋ถ์๋ง
์ฐ๋ฆฌ ๋ทฐ๋ฅผ ๋์ ์ ์๋๋ก ๋์์ฃผ๋ ๊ธฐ๋ฅ์ด์์.
์๋ฅผ ๋ค๋ฉด ๋ค๋น๊ฒ์ด์ ์ปจํธ๋กค๋ฌ๋ ์ฐ๋ฆฌ์ ๋ทฐ ์์ ๋ค๋น๊ฒ์ด์ ๋ฐ๋ฅผ ๋์์ฃผ๋๋ฐ์.
๋ค๋น๊ฒ์ด์ ๋ฐ ๋ฐ์ ๋ถ๋ถ์ ๊ฐ๋ ค์ง ์ ์์ต๋๋ค.
SafeArea ๋ ์ด๋ฐ ๋ทฐ๋ค์ ๋ฐ์ํด์ ๊ฐ์ ๊ณ์ฐํด์ ์๋ ค์ค๋๋ค.
์ ๋ด์ฉ์ ์ข ํฉํด์ ์๋ ๊ทธ๋ฆผ์ ๋ณด๋ฉด
ํ๋์์ผ๋ก ํํ๋ ์ฌ๊ฐํ์ด Safe Area ์ ํด๋นํ๋ ์์ญ์์ ์ฝ๊ฒ ์ดํดํ ์ ์์ต๋๋ค.
Status bar ์ ๋ค๋น๊ฒ์ด์ ๋ฐ, ํด๋ฐ, Home Indicator ์์ญ์ ์ ์ธํ ๋ถ๋ถ์์ ํ์ธํ ์ ์์ฃ ?
Interface Builder ์์ ๋ง๋๋ณด๋ Safe Area
์ฐ๋ฆฌ๋ ์ด ๊ฐ์ Interface Builder ์์ ์ฌ์ฉํ ์ ์๊ณ , ์ฝ๋๋ก๋ ์ฌ์ฉํ ์์๋๋ฐ์.
์ฐ์ Interface Builder ์์ ๋ณด๋ฉด
Safe Area ์ ๊ธฐ์ค์ผ๋ก ์ ์ฝ์ ๊ฑธ์ด์ฃผ์ด์
๋ด ๋ทฐ๊ฐ ์ ๋๋ก ํํ๋๋ ๊ฒ์ ๋ณด์ฅ๋ฐ์ ์ ์์ด์.
์ ์ฝ์ ๊ฑฐ๋ ๋ฐฉ๋ฒ์ ์ด ๊ธ์ ์ฃผ์ ์ ์กฐ๊ธ ๊ฑฐ๋ฆฌ๊ฐ ์์ด์ ์ฌ์ง์ผ๋ก๋ง ๋์ด๊ฐ๊ฒ์!
Code ์์ ๋ง๋๋ณด๋ Safe Area
์ฝ๋์์๋ UIView์ ์ธ์คํด์ค ์์ฑ์ธ safeLayoutGuide ์ผ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค.
Safe Area ๊ฐ ๊ธฐ์กด ๋ทฐ์ ์ผ๋ง ๋งํผ์ ๊ฐ์ ํจ๋ฉ์ผ๋ก ์ฃผ์๋์ง๋
safeAreaInsets ์์ฑ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ!!!!!
์์ชฝ์ Layout Margins ์ ๋ด์ฉ ์ค์์
UIKit ์ ViewController ์ Root View ์ ์ต์ ๋ง์ง๊ฐ ์ ์ค์ ํด ๋๋๋ค๊ณ ๋ง์๋๋ ธ๋๋ฐ์.
์ฌ๊ธฐ์ ์ต์ ๋ง์ง๊ฐ์ด๋, "๋ง์ง ๊ฐ์ด ์ต์ํ ์ด ๊ฐ๋ณด๋ค๋ ์ปค์ผ๋ผ" ๋ผ๋ ์๋ฏธ
๊ทธ ๋ชฉ์ ๋ ์์์ ์ธ๊ธํ์ด์.
( ๋ฃจํธ ๋ทฐ์ ์ปจํ ์ธ ๊ฐ ๊ฐ๋ ค์ง์ง ์๊ณ ์ ํํ๊ฒ ๋์ค๋ ๊ฒ์ ๋ณด์ฅ)
์ด ์ต์ ๋ง์ง๊ฐ์ด ์ ์ฉ๋ ์ฌ๊ฐํ ์์ญ์ด Safe Area ์ ์์ญ๊ณผ ์ ํํ๊ฒ ์ผ์นํด์.
์ฆ, ๋ค๋น๊ฒ์ด์ ๋ฐ์ ๊ฐ์ ์์คํ ๋ทฐ๊ฐ ๋์ค๋ฉด UIKit ์ด ์ด๋ฅผ ๊ณ ๋ คํด์ ์ต์ ๋ง์ง๊ฐ์ ์ค์ ํ๋ค๋ ๊ฒ์ด์ฃ !
๊ทธ๋์, ์ด ์ต์ ๋ง์ง๊ฐ = safeAreaInsets ์ ๋๋ค.
์์ ์๋ systemMinimum ์ด์ฉ๊ตฌํ๋ ์์ฑ์ ์ผ๋๊ฒ ๊ฐ์์.
์ง๊ธ์ ์ ๊ทผ์ด ์๋๋๋ผ๊ตฌ์๐
๊ทธ๋ฐ๋ฐ ์ฝ๊ฐ ์ด์ํ์ง ์๋์?
์ ๋ ์ ์ด ๊ฐ์ viewDidLoad ๊ฐ ์๋๋ผ viewDidAppear ์์ ํ์ธํ์๊น์????
๋ฐ๋ก SafeLayout ๋ฌธ์์ ์ด ๋ถ๋ถ ๋๋ฌธ์ธ๋ฐ์!!!
If the view is not currently installed in a view hierarchy, or is not yet visible onscreen, the layout guide edges are equal to the edges of the view.
๋ทฐ๊ฐ ๋ทฐ๊ณ์ธต์ ์ถ๊ฐ๋์ง ์์๊ฑฐ๋, ์์ง ํ๋ฉด์ ๋ณด์ด์ง ์์๋๋
์์ง Safe Layout Guide ๊ฐ ์ ์ฉ๋๊ธฐ ์ ์ํ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
( ์ด ์์ ์๋ Guide ๊ฐ ์๋ณธ ๋ทฐ์ edge ์ ์ผ์น )
์ฆ, ViewDidLoad ํธ์ถ ์์ ์์๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ทฐ ๊ณ์ธต์ ๋ก๋ฉํ ์ํ์ด์ง๋ง,
ํ๋ฉด์๋ ์์ง ๋ณด์ด์ง ์๊ธฐ ๋๋ฌธ์ Safe Layout Guide ๊ฐ ์ ์ฉ๋์ง ์์ ์ํ์ธ๊ฑฐ์ฃ .
ํ์คํ ํ๊ณ ์ถ์ด์ ๋ก๊ทธ๋ ์ฐ์ด๋ดค์ด์.
(๊ฐ๋ ์ฑ์ ์ํด safeLayoutInsets ๊ฐ ๋ฅผ ํ๋ฆฐํธํ์ต๋๋ค.)
๊ฒฐ๋ก ์ ์ผ๋ก ์ฐ๋ฆฌ๋ ์ด์ ์๋ ๊ทธ๋ฆผ์ ์ดํดํ ์ ์์ต๋๋ค
์ฌ๊ธฐ์ safeAreaLayoutGuide ๋ UIView ์ ์ธ์คํด์ค ์์ฑ์ผ๋ก์ ๋ชจ๋ ๋ทฐ์์ ์ ๊ทผํ ์ ์๋๋ฐ์.
์ค์ ์๋ฏธ ์๋ ๊ฐ์ ๋ฃจํธ ๋ทฐ์๋ง ๋ด๊ฒจ์ ธ ์๋ค๊ณ ์๊ฐํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.
safeAreaInsets ๋ ๋ง์ฐฌ๊ฐ์ง ์ ๋๋ค.
๋ฃจํธ ๋ทฐ์ Safe Area ์์ญ์ด ์ปจํ ์ธ ๋ณด์ฅ์ด ๋๋ค๋ฉด, ๋น์ฐํ ๊ทธ ํ์ ๋ทฐ๋ค์ ๋ฃจํธ ๋ทฐ์ Bounds ๋ฅผ ๋์ด๊ฐ์ง ์๋ํ
๋ฌด์กฐ๊ฑด ์ปจํ ์ธ ๊ฐ ์ ๋๋ก ๋ณด์ฌ์ง ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด์์.
์ด ๊ธ์์ ๋ค๋ฃจ์ง ์๋ ๋ถ๋ถ
๋ด์ฉ์ด ๋๋ฌด ๋ง์์ ๋ด์ง ์์์ง๋ง, ์ฐพ์๋ณผ ์์๋ ํค์๋๋ฅผ ์ ์ํด๋๋ฆฌ๋ ค๊ณ ํฉ๋๋ค.
1. Safe Area ์ ์ฝ๋๋ก ์ ์ฝ์ ์ก์์ฃผ๊ธฐ
์ด ๋ถ๋ถ์ NSLayoutAnchor ์ ๊ฐ๋ ์ ๋ํด์ ์์์ผ ํฉ๋๋ค.
safeAreaLayoutGuide ๊ฐ Anchor ๋ค๋ก ์ด๋ฃจ์ด์ ธ ์๊ธฐ ๋๋ฌธ์ธ๋ฐ์.
๊ฐ๋จํ๊ฒ ์ฃ์ง๋ฅผ ๊ฐ๋ฆฌํค๋ ์ ์ด๋ผ๋ ๊ฐ๋ ์ผ๋ก ์ดํดํ๋ฉด ์ ๊ทผํ๊ธฐ ์ฝ๋๋ผ๊ตฌ์!
2. SafeArea ์์ญ ์ถ๊ฐ๋ก ๋ํ๊ธฐ
์ฌ์ฉ์ ์์๋ก ์์ญ์ ์ถ๊ฐํด์ค ์ ์์ต๋๋ค.
๋ณดํต ํ๋ฉด์ ๋ฎ๋ ์ปค์คํ ๋ทฐ๋ฅผ ๋ฐ๋ก ๊ตฌํํ์ ๋ ํ์ํ๊ฒ ์ฃ !
additionalSafeAreaInsets ์ ์ฌ์ฉํฉ๋๋ค.
๊ด๋ จ ๋ด์ฉ์ ๋งํฌ ํ์ธํด ์ฃผ์ธ์!
์ฌ๊ธฐ๊น์ง ์ฐ์ ์ ๊ฐ ์ ๊ณ ์ถ์ ๊ฒ์ ๋ค ์ ์ ๊ฒ ๊ฐ๊ณ , ์ถ๊ฐํ ๋ด์ฉ์ด ์๊ธฐ๋ฉด ์์ ํ๊ฒ ์ต๋๋ค~!!!
์ด์ ์คํฌ๋กค๋ทฐ์ contentOffset ๊ณผ contentInset ์ ๋ํ ๊ธ์ ์ ์ด์ผํ๋๋ฐ,
์ ๋ 100% ์ดํดํ๊ฒ์ด ์๋๋ผ ์ฝ์ง ์๋ค์....
ํ์ง๋ง ์คํฌ๋กค ๋ทฐ๋ ์ ๋ง์ ๋ง ํ์ํ UI ์ปดํฌ๋ํธ์ด๋ ๊ณง ๋๋ผ ์ ์์ ๊ฒ๊ฐ์์.
๊ทธ๋ผ ๋ค์์ ๋ดด๊ฒ์~!!!
๋!
๐ค๐ข[์ฐ์งฑ์ iOS ๋ธ๋ก๊ทธ]๐ต๐ป
iOS๋ฅผ ๊ณต๋ถํ๋ฉด์ ๋ฐฐ์ด ๋ด์ฉ์ ๊ธฐ๋กํ๊ณ ์์ต๋๋ค.์ฐธ๊ณ ์๋ฃ 1: https://developer.apple.com/documentation/uikit/uiview/positioning_content_within_layout_margins
์ฐธ๊ณ ์๋ฃ 2: https://developer.apple.com/documentation/uikit/uiview/positioning_content_relative_to_the_safe_area/
'iOS > ๐ค App' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] clipsToBounds ์ masksToBounds (2) 2021.10.19 [SSAC ์น] iOS ๊ฐ๋ฐ์ ๋ฐ๋ท๊ณผ์ ํฉ๊ฒฉ ํ๊ธฐ (2021) (2) 2021.09.24 [iOS] Container View Controller ๋? (0) 2021.07.26 [iOS] ๋ฆฌ์คํฐ๋ ์ฒด์ธ (Responder Chain) ์ด๋? (feat. UIResponder, First Responder, UIEvent) (2) 2021.07.12 [iOS] ์๋์ฐ๋? (feat. UIWindow) (0) 2021.07.05