iOS 기본 (SwiftUI)
[iOS - SwiftUI] @EnvironmentObject 사용 방법 (뷰 간 데이터 공유 방법, .environmentObject())
jake-kim
2022. 10. 29. 23:29
@EnvironmentObject 란?
- parent 뷰에서 정의한 observable 객체이며, subview들이 접근 가능한 프로퍼티로 property wrapper 타입
- 즉, parent 뷰에서 subview에 특정 상태를 주입하여, subview에서 그 상태에 접근할때 사용
- subview에서 superview로부터 주입받은 @EnvironmentObject 프로퍼티를 변경시키면 부모에서도 모두 뷰가 업데이트
- 전역적으로 데이터를 공유하는 형태이므로, 뷰 간 데이터를 공유할때 사용
- 내부 코드
- dynamicMember keyPath로 해당 프로퍼티에 접근할때 dot(.)로 접근이 가능
- ObservableObject 타입을 준수할때 사용이 가능
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
@frozen @propertyWrapper public struct EnvironmentObject<ObjectType> : DynamicProperty where ObjectType : ObservableObject {
@dynamicMemberLookup @frozen public struct Wrapper {
public subscript<Subject>(dynamicMember keyPath: ReferenceWritableKeyPath<ObjectType, Subject>) -> Binding<Subject> { get }
}
@inlinable public var wrappedValue: ObjectType { get }
public var projectedValue: EnvironmentObject<ObjectType>.Wrapper { get }
public init()
}
EnvironmentObject 사용하여 뷰간 데이터 공유 방법
- 자식으로 EnvironmentObject 인스턴스를 보내야 하는데, 이 때 모델은 ObservableObject를 준수해야 하므로 따로 모델을 정의
class MyObservableObject: ObservableObject {
@Published var isOn = false
}
- @StateObject로 선언하여 자식에게 넘겨줄 인스턴스 준비
- @StateObject 개념은 이전 포스팅 글 참고
struct ContentView: View {
@StateObject var myObject = MyObservableObject()
var body: some View {
VStack {
Text(myObject.isOn ? "isOn" : "isOff")
}
}
}
- myObject를 하위 뷰로 넘겨주고, 이 때 하위 뷰에서 myObject의 isOn 값을 변경하면 부모 뷰인 ContentView에도 적용이 되는지 확인할 것
- subview인 MyView를 정의하고 이를 ContentView에 subview로 준비
- subview로의 주입은 .environmentObject()로 주입
struct MyView: View {
@EnvironmentObject var myObject: MyObservableObject // ObservableObject타입을 준수해야됨
var body: some View {
Button(myObject.isOn ? "child, isOn" : "child, isOff") {
myObject.isOn.toggle()
print(myObject.isOn)
}
}
}
struct ContentView: View {
@StateObject var myObject = MyObservableObject()
var body: some View {
VStack {
Text(myObject.isOn ? "isOn" : "isOff")
Divider()
MyView() // <-
.environmentObject(myObject)
}
}
}
결과) 자식 뷰 MyView()에서 주입받은 myObject의 isOn 값을 변경하면 부모 뷰에도 isOn값이 변경
* 전체 코드: https://github.com/JK0369/ExEnvironmentObject-SwiftUI
* 참고
https://developer.apple.com/documentation/swiftui/environmentobject