Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- RxCocoa
- Clean Code
- map
- rxswift
- tableView
- ios
- UICollectionView
- MVVM
- collectionview
- 애니메이션
- Observable
- Protocol
- Xcode
- clean architecture
- swift documentation
- 클린 코드
- uitableview
- combine
- SWIFT
- UITextView
- uiscrollview
- Refactoring
- 리펙토링
- HIG
- 스위프트
- 리팩토링
- ribs
- 리펙터링
- Human interface guide
- swiftUI
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] 선언형 프로그래밍 관점으로 코딩하는 방법 (명령형 vs 선언형, 선언적 코딩) 본문
iOS 접근성 (SwiftUI)
[iOS - SwiftUI] 선언형 프로그래밍 관점으로 코딩하는 방법 (명령형 vs 선언형, 선언적 코딩)
jake-kim 2024. 12. 19. 01:45명령형 vs 선언형 코드 작성의 흐름
- 명령형 프로그래밍
- "어떻게" UI를 업데이트할지 명시적으로 작성
let label = UILabel()
label.text = "Hello, World!"
label.textColor = .blue
label.frame = CGRect(x: 0, y: 0, width: 200, height: 50)
view.addSubview(label)
- 선언형 프로그래밍
- 좀 더 코드가 뷰의 형태와 닮은 형태로 작성
struct ContentView: View {
var body: some View {
Text("Hello, World!")
.foregroundColor(.blue)
.frame(width: 200, height: 50)
}
}
ex) 카운터 뷰 만들기
- 선언형 프로그래밍 SwiftUI로 만들면, 뷰의 배치 위치와 동일하게 Text, Button, Button이 나열되어 있고 마치 코드가 뷰의 형태와 닮은 형태처럼 되어서 더욱 직관적인 프로그래밍이 가능
struct ContentView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 20) {
Text("\(count)")
.font(.largeTitle)
.foregroundColor(count < 0 ? .red : .green)
.padding()
Button(action: {
count += 1
}) {
Text("Increment")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
Button(action: {
count -= 1
}) {
Text("Decrement")
.padding()
.background(Color.gray)
.foregroundColor(.white)
.cornerRadius(10)
}
}
.padding()
}
}
- 반면에 명령형 프로그래밍 UIKit으로 작성하면 각 뷰의 속성 (font, addTarget)작성하는 곳과 layout을 작성하는 곳 (오토레이아웃)코드가 분리되어 있어서 직관적이지 않은 단점이 존재
import UIKit
class CounterViewController: UIViewController {
private var count = 0
private let countLabel = UILabel()
private let incrementButton = UIButton(type: .system)
private let decrementButton = UIButton(type: .system)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
countLabel.text = "\(count)"
countLabel.textAlignment = .center
countLabel.font = UIFont.systemFont(ofSize: 32)
countLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(countLabel)
incrementButton.setTitle("Increment", for: .normal)
incrementButton.addTarget(self, action: #selector(incrementCount), for: .touchUpInside)
incrementButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(incrementButton)
decrementButton.setTitle("Decrement", for: .normal)
decrementButton.addTarget(self, action: #selector(decrementCount), for: .touchUpInside)
decrementButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(decrementButton)
NSLayoutConstraint.activate([
countLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
countLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50),
incrementButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
incrementButton.topAnchor.constraint(equalTo: countLabel.bottomAnchor, constant: 20),
decrementButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
decrementButton.topAnchor.constraint(equalTo: incrementButton.bottomAnchor, constant: 20)
])
}
@objc private func incrementCount() {
count += 1
updateUI()
}
@objc private func decrementCount() {
count -= 1
updateUI()
}
private func updateUI() {
countLabel.text = "\(count)"
countLabel.textColor = count < 0 ? .red : .green
}
}
선언적으로 코딩하는 방법
- 위에서 알아본것처럼 선언형 프로그래밍은 코드가 마치 뷰처럼 보여야 하는것이 핵심
- ex) padding을 하나 작성 할 때도 이런 관점이 매우 중요
- 아래 뷰에서 padding을 30만큼 주고 싶은 경우?
struct ContentView: View {
var body: some View {
VStack(spacing: 0) {
Text("첫 번째 text")
.font(.largeTitle)
Text("두 번째 text")
.font(.largeTitle)
}
}
}
- 아래처럼 두 번째 text에다 padding top을 줄 수 있지만, 코드를 읽을 때는 위에서 아래로 읽기 때문에, 가능하면 윗쪽에 bottom padding으로 작성할 것
// bad
struct ContentView: View {
var body: some View {
VStack(spacing: 0) {
Text("첫 번째 text")
.font(.largeTitle)
Text("두 번째 text")
.font(.largeTitle)
.padding(.top, 30) // <-
}
}
}
// good
struct ContentView: View {
var body: some View {
VStack(spacing: 0) {
Text("첫 번째 text")
.font(.largeTitle)
.padding(.bottom, 30) // <-
Text("두 번째 text")
.font(.largeTitle)
}
}
}
Comments