SwiftUI @State @Binding @EnvironmentObject
SwiftUI를 사용하면서 자주 사용하는 프로퍼티 래퍼인데, Skimming 과정에서 너무 헷갈려서 간단히 정리
@State: View 내부의 상태가 변경되어서 처리할 때
@Binding: 다른 View에 있는 상태의 변화를 관찰할 때
@EnvironmentObject: View의 계층 관계가 존재할 때 이를 의존성을 갖출 때
우선 State와 Binding에 대해서 간단히 보자
아래는 새믈 코드
struct FirstView: View {
@State private var appTitle = tabIndex.first.rawValue
@State private var count = 0
enum tabIndex: String {
case first = "1번뷰 입니다."
case second = "2번뷰 입니다."
case third = "3번뷰 입니다"
}
var body: some View {
TabView {
VStack {
Text("스위프트 유아이를 정복해봅시다. count: \(count)")
.padding()
Button {
count += 1
} label: {
Text("카운트 업")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
.tabItem { Label("1번 뷰", systemImage: "pencil.circle") }
SecondView(count: $count)
.tabItem { Label("2번 뷰", systemImage: "pencil.circle") }
ThirdView(count: $count)
.tabItem { Label("3번 뷰", systemImage: "pencil.circle") }
}
}
}
struct SecondView: View {
@Binding var count: Int
init(count: Binding<Int> = .constant(0)) {
_count = count
}
var body: some View {
VStack {
Text("2번뷰입니다. \(count)")
Button {
count += 1
} label: {
Text("카운트 업")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
}
}
struct ThirdView: View {
@Binding var count: Int
init(count: Binding<Int> = .constant(0)) {
_count = count
}
var body: some View {
VStack {
Text("2번뷰입니다. \(count)")
Button {
count += 1
} label: {
Text("카운트 업")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
}
}
스크린샷
아래는 샘플 코드에 대한 스크린 샷



1번 뷰는 @State를 가지고 있고 2,3번 뷰는 Binding하고 있어서 1번 뷰의 상태가 변화하면 2번 뷰가 함께 달라짐
동일한 @State에 연결된 @Binding에 값들은 모두 함께 반영됨
@EnvironmentObject에 대해서 살펴보자.
사용 순서 정리
- 1. ObservableObject를 ViewModel에서 상속받기
- 2. 해당 View에 environment를 사용하여 ViewModel을 넣어주기
샘플 코드
의존성 가져다가 쓸 수 있다.
약간 Needle 방향보다는 SwiftInject의 형태와 닮아있다.
import Combine
import SwiftUI
class GlobalStore: ObservableObject {
@Published var count: Int = 0
}
struct EnvironmentSampleView: View {
var store = GlobalStore()
var body: some View {
VStack {
Button(action: {
store.count += 1
}, label: { Text("BUTTON") })
ChildView()
.environmentObject(store)
}
}
}
struct ChildView: View {
@EnvironmentObject var store: GlobalStore
var body: some View {
Text("\(store.count)")
}
}

'apple > SwiftUI, Combine' 카테고리의 다른 글
| SwiftUI TextField, SecureField (0) | 2022.05.23 |
|---|---|
| SwiftUI ButtonStyle 적용해보기 (0) | 2022.05.23 |
| SwiftUI TabView (Custom TabView) (0) | 2022.05.19 |
| SwiftUI GeometryReader (0) | 2022.05.19 |
| SwiftUI NavigationView (0) | 2022.05.18 |