-
[iOS] SnapKit ์ฌ์ฉํ๊ธฐiOS 2022. 5. 10. 03:46
SnapKit์ด๋?
๊ฐ๊ฒฐํ ์ฝ๋๋ก NSLayoutConstraint๋ฅผ ์ฝ๊ฒ ์ ์ดํ ์ ์๋๋ก ํด์ค๋ค. ์ฆ, ์งง์ ์ฝ๋๋ก ์คํ ๋ ์ด์์์ ๊ตฌํํ ์ ์๋๋ก ๋์์ฃผ๋ ํ๋ ์์ํฌ์ด๋ค.
์คํ ๋ ์ด์์ ๋ฐ ์ ์ฝ ์กฐ๊ฑด์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ DSL (Domain-specific language).
DSL์?!
Domain specific language (DSL)์ ํน์ ๋๋ฉ์ธ์ ํํ, ์ฒ๋ฆฌํ๊ฑฐ๋ ํน์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ง๋ค์ด์ง ์ธ์ด์ด๋ค.
SnapKit์ ๊ฒฝ์ฐ, ์คํ ๋ ์ด์์ ์ ์ฝ ์กฐ๊ฑด์ ๋ํด ํจ์ฌ ๋ ์ง๊ด์ ์ด๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๊ตฌ๋ฌธ์ ๋ง๋๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ค.
๋จผ์ ์ฝ์ฝ์ํ์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐํ๊ธฐ!
https://github.com/SnapKit/SnapKit
pod 'SnapKit', '~> 5.6.0'์ด๋ ๊ฒ import SnapKit์ ํ๋ฉด ์ฌ์ฉํ ์ ์์!

์ด์ SnapKit์ ์ฌ์ฉํ๋ฉด, ์๋ ์ฝ๋๋ฅผ ์ธ ํ์๊ฐ ์๋ค.
translatesAutoresizingMaskIntoConstraints = false์๋?! SnapKit์ด ๋ด๋ถ์์ ์์์ ํด์ฃผ๊ธฐ ๋๋ฌธ์!
๐ก translatesAutoresizingMaskIntoConstraints
UIView์ ์ธ์คํด์ค ํ๋กํผํฐ๋ก, ๋ทฐ์ autoresizing mask๋ฅผ AutoLayout constraints๋ก ๋ณํํ ์ง์ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ bool ๊ฐ์ ์๋ฏธํ๋ค.
๊ธฐ๋ณธ๊ฐ์ด true์ด๊ธฐ ๋๋ฌธ์, ๋ทฐ๋ฅผ ์ฝ๋๋ก ์ง ๋ค๋ฉด ์ด ๊ฐ์ ํญ์ false๋ก ์ค์ ํด์ผํ๋ค.
์๋ ์ฝ๋๋ฅผ ์์๋ก ๋ณด์.
child.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ child.leadingAnchor.constraint(equalTo: parent.leadingAnchor), child.topAnchor.constraint(equalTo: parent.topAnchor), child.trailingAnchor.constraint(equalTo: parent.trailingAnchor), child.bottomAnchor.constraint(equalTo: parent.bottomAnchor), ])์ ์ฝ๋๋ฅผ SnapKit์ ์ฌ์ฉํ์ฌ ๋ณํํ๋ฉด ์๋์ ๊ฐ๋ค.
child.snp.makeConstraints { make in make.leading.equalToSuperview() make.top.equalToSuperview() make.trailing.equalToSuperview() make.bottom.equalToSuperview() }SnapKit์ ์์คํ ์ ๋ชจ๋ UIView์ snp์ด๋ namespace๋ฅผ ๋์ ํ๋ค.
snp์ makeConstraints(_:) ๋ฉ์๋์ ํจ๊ป SnapKit์ ํ์ ์์์ด๋ค.
์ ๋ ์ฝ๋๋ ๋น์ทํด๋ณด์ด์ง๋ง, ๊ฐ๋ ์ฑ์ด ๋งค์ฐ ๊ฐ์ ๋์๊ณ ํ์ธํ ์ ์๋ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ๋ค.
- SnapKit์ equalToSuperView() ๋๋ถ์, parent๋ฅผ ์ฐธ์กฐํ ํ์๊ฐ ์ ํ ์๋ค. ์ฆ, child๊ฐ ๋ค๋ฅธ parent view๋ก ์ด๋ํด๋ ์ฝ๋๋ฅผ ์์ ํ ํ์๊ฐ ์๋ค๋ ๊ฒ์ด๋ค.
- make๋ ๊ฑฐ์ ์์ด์ ๋น์ทํ ๊ตฌ๋ฌธ์ ๋ง๋ค์ด๋ธ๋ค. make ๊ตฌ๋ฌธ์ “leading์ด superview์ ๋์ผํ๋๋ก ๋ง๋ค์ด๋ผ”๋ผ๊ณ ์ฝ๋ ๊ฒ์ด ์ข๋ค.
์๋์ ๊ฐ์ด ์ฐ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
child.snp.makeConstraints { $0.leading.equalToSuperview() $0.top.equalToSuperview() $0.trailing.equalToSuperview() $0.bottom.equalToSuperview() }Composability & Chaining
SnapKit์ ๊ฐ์ฅ ํฐ ํน์ง์ composition ๊ธฐ๋ฅ์ด๋ค. ์ ์ฝ ์กฐ๊ฑด ์์ฒด ๋ฟ๋ง ์๋๋ผ, ๋ชจ๋ anchor๋ค๋ ํจ๊ป ์ฐ๊ฒฐํ ์ ์๋ค.
์์์์ ์์ ์ฝ๋๋ฅผ ๋ค์ ์์ฑํ๋ฉด ์๋์ ๊ฐ๋ค.
child.snp.makeConstraints { make in make.leading.top.trailing.bottom.equalToSuperview() }๋๋, edges๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๊ฐ๋จํ๊ฒ ์ธ ์ ์๋ค.
child.snp.makeConstraints { make in make.edges.equalToSuperview() }inset์ ์ถ๊ฐํ๊ณ ์ถ๋ค๋ฉด, ๊ฐ๋จํ๊ฒ chaining์ ์ถ๊ฐํ๋ฉด ๋๋ค.
child.snp.makeConstraints { make in make.edges.equalToSuperview().inset(16) }์์ ๊ฐ์ด Composability์ chaining์ SnapKit์ ํต์ฌ์ผ๋ก, NSLayoutConstraints๋ก๋ ์ ๋ ๋ํ๋ผ ์ ์๋ ํํ๋ ฅ์ ์ ๊ณตํ๋ค.
์๋์ ์์๋ฅผ ๋ณด์.
// Before myLabel.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ myLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.45), myLabel.heightAnchor.constraint(equalToConstant: 45), myLabel.topAnchor.constraint(equalTo: viewProgress.bottomAnchor, constant: 32), myLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor) ]) // After myLabel.snp.makeConstraints { make in make.width.equalToSuperview().multipliedBy(0.45) // 1 make.height.equalTo(45) // 2 make.top.equalTo(viewProgress.snp.bottom).offset(32) // 3 make.centerX.equalToSuperview() // 4 }- 1 - ๋ผ๋ฒจ์ width๋ฅผ ์ํผ๋ทฐ ๋๋น์ 0.45๋ฐฐ๋ก ์ค์
- 2 - ๋ผ๋ฒจ์ height๋ฅผ 45๋ก ์ค์
- 3 - ๋ผ๋ฒจ์ top์ progress bar์ bottom์ผ๋ก ์ ์ฝ์ ์ฃผ๋, offset์ 32๋งํผ ์ค์
- 4 - x์ถ์ ์ํผ๋ทฐ์ x์ถ์ ๋ง์ถฐ์, ๋ผ๋ฒจ์ ์ํ์ผ๋ก ์ค์์ ๋ฐฐ์น
๋ ๋ค๋ฅธ ์์๋ฅผ ํ๋ ๋ณด์.
anotherLabel.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ anotherLabel.topAnchor.constraint(equalTo: myLabel.bottomAnchor, constant: 24), anotherLabel.leadingAnchor .constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16), anotherLabel.trailingAnchor .constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16) ])์์ ์ ์ฝ ์กฐ๊ฑด๋ค์ SnapKit์ผ๋ก ๋ณ๊ฒฝํ๋ฉด ์๋์ ๊ฐ๋ค.
make.top.equalTo(myLabel.snp.bottom).offset(24) make.leading.equalToSuperview().offset(16) make.trailing.equalToSuperview().offset(-16)ํ์ง๋ง ์ฌ์ค ์ฌ๊ธฐ์ leading๊ณผ trailing anchor๊ฐ ๊ฐ์ ์ญํ ์ ํ๊ณ ์๋๋ฐ, ์ด๋ฅผ ๋ ์๋์ ๊ฐ์ด ๋ํ๋ผ ์ ์๋ค.
anotherLabel.snp.makeConstraints { make in make.top.equalTo(lblTimer.snp.bottom).offset(24) make.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(16) }- leading, trailing์ด chain๋์ด์๋ค.
- ๋ทฐ์ ์ ์ฝ์ ์ฃผ๊ธฐ ์ํด ํญ์ snp์ ์ฌ์ฉํ ํ์๋ ์๋ค. ์ด๋ฒ์๋ UILayoutGuide๋ฅผ ์ฌ์ฉํ๋ค.
๋ํ inset ์ต์ ์ด ํญ์ ์ซ์์ผ ํ์๋ ์๋ค. UIEdgeInsets๋ฅผ ๋ฃ์ด๋ ๋๋ค.
make.leading.trailing.equalTo(view.safeAreaLayoutGuide) .inset(UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16))๋ํ, SnapKit์ ํน์ ์ ์ฝ ์กฐ๊ฑด์ ์ถ๋ก ํ ์ ์๋ค.
// Before myButtons.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ myButtons.leadingAnchor.constraint(equalTo: anotherLabel.leadingAnchor), myButtons.trailingAnchor.constraint(equalTo: anotherLabel.trailingAnchor), myButtons.topAnchor.constraint(equalTo: anotherLabel.bottomAnchor, constant: 16), myButtons.heightAnchor.constraint(equalToConstant: 80) ]) // After myButtons.snp.makeConstraints { make in make.leading.trailing.equalTo(anotherLabel) make.top.equalTo(anotherLabel.snp.bottom).offset(16) make.height.equalTo(80) }์ฌ๊ธฐ์ leading๊ณผ trailing์ constraint๊ฐ ๋จ์ํ anotherLabel๊ณผ ๊ฐ๋ค๊ณ ์ ์ํ๊ธฐ๋ง ํ๋ฉด, SnapKit์ ์์์ ์ถ๋ก ํ์ฌ ์ ์ฝ์ ์ค์ ํ๋ค.
์๋ ์์์์๋ ๋ง์ฐฌ๊ฐ์ง๋ก, otherView์ ํน์์ฑ์ ํ์ํ์ง ์๋ค.
SnapKit์ ๊ด๊ณ์์ ์ฒซ๋ฒ์งธ ๋ทฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ค ์ข ๋ฅ์ ์ ์ฝ ์กฐ๊ฑด์ ์์ฑํด์ผ ํ๋์ง ์๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค!
// Original Code view.snp.makeConstraints { make in make.width.equalTo(otherView.snp.width) make.centerX.equalTo(otherView.snp.centerX) } // Could be written as 1: view.snp.makeConstraints { make in make.width.equalTo(otherView) make.centerX.equalTo(otherView) } // Could be written as 2: view.snp.makeConstraints { make in make.width.centerX.equalTo(otherView) }To be continue..
์ฐธ๊ณ ๋ฌธ์
SnapKit for iOS: Constraints in a Snap
In this tutorial you’ll learn about SnapKit, a lightweight DSL (domain-specific language) to make Auto Layout and constraints a breeze to work with.
www.raywenderlich.com
'iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] safeAreaLayoutGuide (0) 2022.05.26 [iOS] SwiftLint ์ ์ฉํ๊ธฐ (0) 2022.05.10 [iOS] Xib ์ฌ์ด์ฆ ๋ณ๊ฒฝํ๊ธฐ (0) 2022.04.09 [iOS] Xcode 13.3, Swift 5.6 warning on self (์๋ฌธ ํด๊ฒฐ ๋ชปํจ) (0) 2022.04.06 [iOS] UITextField extension์ผ๋ก ๊ตฌํํ ๋ NSObject๋ฅผ ์์ํด์ผํ๋ ์ด์ (0) 2022.04.01