티스토리 뷰

SwiftUI에서 Data Binding에 쓰이는 어노테이션들을 정리해보았습니다.

 

@State

같은 struct 내에서만 접근 가능

struct ParenttView: View {

    @State var state: Int = 0

    var body: some View {
        VStack {
            ChildView(state: $state)
        }
    }
}

 

@Binding

다른 struct의 State 참조 가능

 

부모 뷰에 @State 변수를 생성해주고

자식 뷰에는 @Binding 변수를 생성해준 후

자식 뷰 인스턴스의 파라미터로 State 변수를 전달해 주면 됩니다.

struct ParenttView: View {

    @State var state: Int = 0

    var body: some View {
        VStack {
            ChildView(state: $state)
        }
    }

}

struct ChildView :View{

    @Binding var state: Int

    var body: some View{
        Text("\\(self.state)")
    }

}

 

@ObservedObject

다른 클래스의 변수 구독 가능

 

즉, 아예 View를 벗어난 외부에서 State 기능을 사용할 수 있게 해줍니다.

ObservableObject는 이를 구현해주는 프로토콜이고 ViewModel을 만들때 주로 이것을 사용합니다.

(ObervableObject, ObservedObject 는 다름에 주의)

// ViewModel.siwft
class StateViewModel: ObservableObject {

    @Published var state: Int = 0
}

// View.swift
struct ContentView: View {

    @ObservedObject var state = StateViewModel()

    var body: some View {
        Text("\\(self.state)")
    }

}

여기서 @Published를 지운다면 값만 변경되고 UI는 업데이트 되지 않습니다.

이때 objectWillChange.send()를 통해 뷰를 다시 그려 UI를 업데이트할 수 있습니다.

이를 이용하면 조건부로 UI를 업데이트하는 기능을 구현할 수 있습니다!

 

@StateObject

ObservedObject와 같은 역할을 하지만 View가 다시 그려 질 때 새로 생성되지 않아 값 유지

// ViewMoel.swift
class StateViewModel: ObservableObject {

    @Published var state: Int = 0

}

// View.swift
struct ContentView: View {

    @StateObject var state = StateViewModel()

    var body: some View {
        Text("\\(self.state)")

    }
}

 

@EnvironmentObject

부모로부터 상속 가능

 

최상위에 선언해주면 전역 변수로 사용할 수 있습니다.

모든 뷰가 사용해야하는 상태변수가 필요할 때 유용합니다!

 

AppDelegate, SceneDelegate를 사용한다면 아래와 같이,

// SceneDelegate.swift
window.rootViewController = UIHostingController(
	rootView: ContentView().environmentObject(StateViewModel())
)

순수 SwiftUI로만 구성한다면 아래와 같이 루트에서 객체를 생성하고 등록하면 됩니다.

// 진입 지점
@main
struct MyApp: App {
    @StateObject var stateViewModel = StateViewModel()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(stateViewModel)
        }
    }
}

 

생성한 객체는 @EnvironmentObject 어노테이션를 이용해서 모든 자식뷰, 즉 앱 전역에서 사용할 수 있습니다. 

struct ChildTextView:View{

    @EnvironmentObject var StateViewModel: StateViewModel

    var body: some View{
        Text("\\(self.StateViewModel.state)")

    }
}

 

 


Ref.

SwiftUI 튜토리얼 5편 - @State, @Binding, @ObservedObject

[SwiftUI] 뷰 상태변경 @State @Binding @ObservedObject @StateObject

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함