@EnvironmentObject
- 앱 전역에서 공유되는 객체 데이터를 설정할 수 있는 프로퍼티 래퍼
뷰 간 데이터 공유
ObservableObject
를 채택한 객체 데이터를 @StateObject
와 @ObservedObject
를 통해 뷰 간에 공유할 수 있다.
- 하지만 이 방법은 직접적으로 데이터를 사용하지 않더라도 전달만을 위해 인스턴스를 생성해야하는 상황이 발생한다.
class EnvironmentViewModel: ObservableObject {
@Published var dataArray: [String] = []
init() {
getData()
}
func getData() {
self.dataArray.append(contentsOf: ["iPhone", "iPad", "iMac"])
}
}
struct FirstView: View {
@StateObject var viewModel: EnvironmentViewModel = EnvironmentViewModel()
var body: some View {
NavigationStack {
List {
ForEach(viewModel.dataArray, id: \.self) { item in
NavigationLink {
SecondView(viewModel: viewModel, selectedItem: item)
} label: {
Text(item)
}
}
}
}
}
}
struct SecondView: View {
@ObservedObject var viewModel: EnvironmentViewModel
let selectedItem: String
var body: some View {
NavigationLink {
ThirdView(viewModel: viewModel)
} label: {
Text(selectedItem)
}
}
}
struct ThirdView: View {
@ObservedObject var viewModel: EnvironmentViewModel
var body: some View {
ForEach(viewModel.dataArray, id: \.self) { item in
Text(item)
}
}
}
@EnvironmentObject
@StateObject
로 생성한 객체 데이터를 .environmentObject()
를 통해 하위 뷰 전역에 공유할 수 있다.
- 공유 받은 하위 뷰에서는 데이터가 필요한 특정 뷰까지의 불필요한 전달없이
@EnvironmentObject
를 통해 바로 사용할 수 있다.
struct FirstView: View {
@StateObject var viewModel: EnvironmentViewModel = EnvironmentViewModel()
var body: some View {
NavigationStack {
List {
ForEach(viewModel.dataArray, id: \.self) { item in
NavigationLink {
SecondView(selectedItem: item)
} label: {
Text(item)
}
}
}
}
.environmentObject(viewModel)
}
}
struct SecondView: View {
let selectedItem: String
var body: some View {
NavigationLink {
ThirdView()
} label: {
Text(selectedItem)
}
}
}
struct ThirdView: View {
@EnvironmentObject var viewModel: EnvironmentViewModel
var body: some View {
ForEach(viewModel.dataArray, id: \.self) { item in
Text(item)
}
}
}