์์ ๋ค์ ์ฝ๋ ๋ฒ ์ด์ค๋ก UI๋ฅผ ์ง๊ณ , ํ๋ก๊ทธ๋๋ฐ์ ํ๊ณ ์๋ค. ์ํธ ์ธ๋ฏธ๋ ํ ๋ ์คํ ๋ฆฌ๋ณด๋๋ฅผ ๋๋ฌด ๋ง์ด ๋ดค๋์ง ์ ์ ๋ฉ๋ฆฌ ํ ๋๊ฐ ๋ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ ์ค์ค๋ก ํ๋ค... ์ถฉ๋ถํ ๋ง์ด ๋ดค์ด...๐ ์ฌ์ค ์ฝ๋ ๋ฒ ์ด์ค๋ก UI๋ฅผ ์งค ๋ ํญ์ ๊ณ ๋ฏผ์ ํ๋ ๋ถ๋ถ์ ์ฝ๋๊ฐ ๋๋ฌด ๊ธธ์ด์ง๊ณ ๊ฐ๋ ์ฑ์ด ์ข์ง ์๋ค๋ ๊ฒ์ด์๋ค.
์์น ๊ณผ์ ์ธ Diary ์ฑ์ ๋ง๋ค๋ฉด์ ๋ฌธ๋ ๋ ์๊ฐ์ด ๋ค์ด์ ์คํ์ผ์ ์ข ๋ฐ๊พธ๋ ค๊ณ ์๋ํด๋ณด์๋ค.
Then (Syntax Sugar Library)๋ฅผ ์ฌ์ฉํ๋ค๋ ๊ฐ์ ํ์ UI ์ง๋ ์คํ์ผ์ ํ ๋ฒ ์ดํด๋ณด์.
1. ์ธ์คํด์ค ์์ฑ ์์ ํด๋ก์ ๋ก ์์ฑ๊น์ง ์ง์ ํด์ฃผ๋ ๋ฐฉ๋ฒ
UI ๊ฐ์ฒด๊ฐ ๋ช ๊ฐ ์๋ค๋ฉด ์คํ๋ ค ๊น๋ํ๊ณ ๊ฐ๋ ์ฑ๋ ์ข์ ๊ฒ ๊ฐ๋ค.
let blackView = UIView().then {
$0.backgroundColor = .black
}
let nameLabel = UILabel().then {
$0.text = "text"
$0.textColor = .blue
$0.backgroundColor = .red
}
override func viewDidLoad() {
super.viewDidLoad()
configureLayout()
}
private func configureLayout() {
[blackView, nameLabel].forEach {
view.addSubview($0)
}
blackView.snp.makeConstraints {
$0.width.height.equalTo(200)
$0.top.equalTo(view.safeAreaLayoutGuide)
$0.centerX.equalTo(view)
}
nameLabel.snp.makeConstraints {
$0.edges.equalTo(blackView).inset(50)
}
}
2. ์์ฑ์ ๋ฉ์๋์์ ์ง์ ํด์ฃผ๋ ๋ฐฉ๋ฒ
์์ฑ์ ๊ฐ์ฒด ๋ณ๋ก ๋ฉ์๋๋ฅผ ๋๋์ด ์ง์ ํ๋ ๋ฐฉ๋ฒ(- ๋ค์ด๋ฐ ํ๋ ๊ฒ๋ ๋จธ๋ฆฌ ์ํ๋ค -)๋ ์๊ณ , ์์์๋ configureAttributes ๋ฉ์๋ ์์ ์์ฑ ์ค์ ํ๋ ์ฝ๋๋ฅผ ์ ๋ถ ๋๋ ค๋ฐ์๋ค. ๋ฒ์จ ๋ณ๋ก์ธ ๊ฒ ๊ฐ๋ค. ์์ฑ ๊ตฌ๋ถ๋ ์ ๋๊ณ ๊ฐ๋ ์ฑ์ด ๋ณ๋ก ์ข์ง ์๋ค. (UI ์์๊ฐ ๋ ๋ง์์ง๋ ์ํฉ์ ์๊ฐํด๋ณด์.)
let blackView = UIView()
let nameLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
configureAttributes()
configureLayout()
}
private func configureAttributes() {
blackView.backgroundColor = .red
nameLabel.text = "text"
nameLabel.textColor = .blue
nameLabel.backgroundColor = .red
}
private func configureLayout() {
[blackView, nameLabel].forEach {
view.addSubview($0)
}
blackView.snp.makeConstraints {
$0.width.height.equalTo(200)
$0.top.equalTo(view.safeAreaLayoutGuide)
$0.centerX.equalTo(view)
}
nameLabel.snp.makeConstraints {
$0.edges.equalTo(blackView).inset(50)
}
}
์์์ ์ดํด๋ณธ ๋ ๊ฐ์ง์ ์คํ์ผ์ ์ด๋ ํ๊ฐ? ์ฌ์ค ์ด๋ค ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ๊ฒ์ธ์ง๋ ์ทจํฅ ์ฐจ์ด์ธ ๊ฒ ๊ฐ๋ค. ๋ง์ ๋ ํฌ์งํฐ๋ฆฌ๋ฅผ ์ดํด๋ณด๋ฉด ์ ์๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒ ๊ฐ์๋ฐ UI ์ธ์คํด์ค ์๊ฐ ์กฐ๊ธ์ด๋ผ๋ ๋ง์์ง๋ฉด ์๋นํ ๊ฐ๋ ์ฑ์ด ๋ณ๋ก๋ผ๊ณ ๋๊ปด์ง๋ค. (๊ฐ์ธ์ ์ธ ์๊ฐ) - RootView๋ง ๋ฏ์ด์ ๋ฐ๋ก UI๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ์์ ์ ์ฉํ๋ค๊ณ ํ๋๋ผ๋ ๊ฐ์ ๋ฌธ์ ์ ์ ๊ทธ๋๋ก ์๋ค. ๋๋ UI ์ธ์คํด์ค๊ฐ ์ญ ๊ฐ์ง๋ฐํ์ผ๋ฉด ์ข๊ฒ ์ด์ ํ์์ ๋ฐฉ๋ฒ์ Then ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ do ๋ฉ์๋๋ฅผ ์ด์ฉํด๋ณด๊ธฐ๋ก ํ๋ค. (๋งจ๋ Then ๋ฉ์๋๋ง ์ฐ๋ค๋ณด๋๊น ๋ค๋ฅธ ๋ฉ์๋๊ฐ ์๋์ง๋ ๋ชฐ๋๋ค.)
๋ค์๊ณผ ๊ฐ์ ๋ ์ด์์์ ๊ตฌ์ฑํ๋ค๊ณ ๊ฐ์ ํ๊ณ ๋ณด๋๋ก ํ์.
Then ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ do ๋ฉ์๋ ์ด์ฉ
UI ํ๋กํผํฐ์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ๋ ์์ฑ๊น์ง ํ ๋ฒ์ ์ง์ ํด์คฌ์๋๋ฐ ์ฝ๋๊ฐ ์ข ์ง์ ๋ถํด์ง๊ณ , UI ์์๋ง ๋ถ๋ฆฌ์์ผ์ ๋ณด๊ณ ์ถ๋ค๋ ์๊ฐ์ด ๊ณ์ ๋ค์์๋ค. ๊ทธ๋ ๋ค๊ณ ์์ฑ์ ํ๋์ ๋ฉ์๋ ์์์ ์ญ ์ ์ด์ฃผ์๋ ๊ทธ๊ฒ๋ ๊ฐ๋ ์ฑ์ด ์ข์ง ์์๋ค. Then ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ do ๋ฉ์๋ ์ด์ฉํด๋ณด๊ธฐ๋ก ํ๋ค.
์ด๋ ๊ฒ ์์ฑํ๊ณ ๋๋ ํ์(์์ฑ์ ๋ฉ์๋์์ ์ง์ ํด์ฃผ๋ ๋ฐฉ๋ฒ)์ ๋ฌธ์ ์ ์ด์๋ ๊ฐ๋ ์ฑ์ด ์ ์ข๋ค๋ ๊ฒ์ด ์ข ํด๊ฒฐ๋ ๋ฏ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ํ๋ ๊ฒ์ฒ๋ผ UI ์ธ์คํด์ค๋ฅผ ๊ฐ์ง๋ฐํ ๋ณผ ์ ์๊ฒ ๋์๋ค.
final class PhotoSearchView: BaseView {
lazy var searchBar = UISearchBar()
lazy var collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout())
override func configureAttributes() {
searchBar.do {
$0.placeholder = "์ฌ์ง์ ๊ฒ์ํด๋ณด์ธ์."
$0.searchTextField.font = .systemFont(ofSize: 14)
$0.searchTextField.backgroundColor = .clear
}
collectionView.do {
$0.register(PhotoCell.self, forCellWithReuseIdentifier: PhotoCell.reuseIdentifier)
let layout = UICollectionViewFlowLayout()
let spacing = 8.0
let cellWidth = (UIScreen.main.bounds.width - spacing * 2) / 3
layout.itemSize = CGSize(width: cellWidth, height: cellWidth)
layout.minimumInteritemSpacing = spacing
$0.collectionViewLayout = layout
}
}
...
}
๋ง๋ฌด๋ฆฌ
์ค๋ ์์ฑํ ๋ด์ฉ์ ์ ๋ง ๊ฐ์ธ์ ์ธ ์ทจํฅ, ์๊ฐ์ด๊ธฐ ๋๋ฌธ์ ์ฐธ๊ณ ๋ง ํ์ผ๋ฉด ์ข๊ฒ ๋ค. ์ฝ๋ ์์ฑ ์คํ์ผ์ ๊ฐ์ธ ์ทจํฅ์ด๋๊น!