Как изменить @EnvironmentObject из класса, а не из представления

У меня есть TabView с двумя дочерними представлениями - PageOneView и PageTwoView. У меня также есть данные @EnvironmentObject, инициализированные в SceneDelegate. У меня также есть вложенный дочерний элемент для каждого из PageOneView и PageTwoView. Для PageTwoView вложенный дочерний элемент также является представлением, и внутри него я могу получить доступ и изменить @EnvironmentObject, и все представления верхнего уровня (PageOneView и PageTwoView) отражают изменение. Но для PageOneView вложенный дочерний элемент - это класс, а не представление, и когда я пытаюсь изменить его в дочернем элементе PageOneView, я получаю сообщение об ошибке: Поток 1: Неустранимая ошибка: ObservableObject типа Data не найден. View.environmentObject(_:) для данных может отсутствовать как предок этого представления. Есть ли способ изменить @EnvironmentObject из вложенного дочернего элемента, который не является представлением, а классом?

struct AppView: View {
        
        @EnvironmentObject var data: Data
        
        var body: some View {
            TabView {
                PageOneView().environmentObject(data)
                    .tabItem {
                        Text("PageOne")
                    }
    
                PageTwoView().environmentObject(data)
                    .tabItem {
                        Text("PageTwo")
                    }
                
                
            }
        }
    }

struct PageTwoView: View {
    
    @EnvironmentObject var data: Data
    
    var body: some View {
        VStack {
            Text("Data: \(data.Name)")
            ChildView()//.environmentObject(data)
        }
    }
}

struct ChildView: View {
    
    @EnvironmentObject var data: Data
    
    var body: some View {
        VStack {
            Text("Data: \(data.Name)")
        
            Button(action: {
            self.updateData()
            }) {
                Text("Update Data")
            }
        
        }
    }
    
    func updateData() 
    {
        self.data.Name = "Updated Name"
        
    }
}

struct PageOneView: View {
    
    @EnvironmentObject var data: Data
    
    var body: some View {
        
        VStack {
            Text("Data: \(data.Name)")
        
            Button(action: {
            self.updateData()
            }) {
                Text("Update Data")
            }
        
        }
    }
    
    func updateData()
    {
        var child = Child()
        child.updateData()
        
    }
    
}

class Child: NSObject{

     @EnvironmentObject var data: Data
    
    func updateData()
    {
        data.Name = "Updated Name Again"
    }
}

1 ответ

Решение

Вот исправленная часть (вам не нужно @EnvironmentObject обертка в классе, она предназначена для View, вашего Data - это сам класс, поэтому вы можете передать его экземпляр по ссылке на свой Child)

    func updateData()
    {
        var child = Child(data: self.data)
        child.updateData()
        
    }
    
}

class Child: NSObject{

    let data: Data

    init(data: Data) {
      self.data = data
    }
    
    func updateData()
    {
        data.Name = "Updated Name Again"
    }
}
Другие вопросы по тегам