Manipulating EnvironmentObject inside ObservedObject without getting entire view updated

67 views Asked by At

Using a wrapper allows us to pass EnvironmentObject down into ObservedObject. Nice approach..

But what if you want to manipulate the userData inside ViewObject without an entirely new ViewObject being created every time?

In my app entire view is recreated after I change EnvironmentObject and i don't know how to avoid this.

struct MyCoolView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        MyCoolInternalView(ViewObject(id: self.userData.UID))
    }
}

struct MyCoolInternalView: View {
    @EnvironmentObject var userData: UserData
    @ObservedObject var viewObject: ViewObject

    init(_ viewObject: ViewObject) {
        self.viewObject = viewObject
    }

    var body: some View {
            Text("\(self.viewObject.myCoolProperty)")
    }
}
1

There are 1 answers

2
Asperi On

But what if you want to manipulate the userData inside ViewObject without an entirely new ViewObject being created every time?

Here is a demo of possible solution - make viewObject as StateObject (this will make it persistent through view refresh) and inject userData into it

Tested with Xcode 12.1 / iOS 14.1

class UserData: ObservableObject {
    @Published var UID = "1"
}

class ViewObject: ObservableObject {
    var userData: UserData?
    @Published var myCoolProperty = "Hello"
}

struct MyCoolView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        MyCoolInternalView(self.userData)
    }
}

struct MyCoolInternalView: View {
    @StateObject private var viewObject = ViewObject()

    init(_ userData: UserData) {
        self.viewObject.userData = userData
    }

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