Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize @StateObject with a parameter in SwiftUI

I would like to know if there is currently (at the time of asking, the first Xcode 12.0 Beta) a way to initialize a @StateObject with a parameter coming from an initializer.

To be more specific, this snippet of code works fine:

struct MyView: View {   @StateObject var myObject = MyObject(id: 1) } 

But this does not:

struct MyView: View {   @StateObject var myObject: MyObject    init(id: Int) {     self.myObject = MyObject(id: id)   } } 

From what I understand the role of @StateObject is to make the view the owner of the object. The current workaround I use is to pass the already initialized MyObject instance like this:

struct MyView: View {   @ObservedObject var myObject: MyObject    init(myObject: MyObject) {     self.myObject = myObject   } } 

But now, as far as I understand, the view that created the object owns it, while this view does not.

Thanks.

like image 541
Emilio Schepis Avatar asked Jun 29 '20 10:06

Emilio Schepis


People also ask

What is difference between state and StateObject in SwiftUI?

For Objects use the @StateObject property wrapper. For String, Int, etc use @State property wrapper. @State : We use this property wrapper when we observe a property that is exists inside our ContentView.

What is Observedobject SwiftUI?

A property wrapper type that subscribes to an observable object and invalidates a view whenever the observable object changes.

What is StateObject SwiftUI?

@StateObject var model = DataModel() SwiftUI creates a new instance of the object only once for each instance of the structure that declares the object. When published properties of the observable object change, SwiftUI updates the parts of any view that depend on those properties: Text(model.


1 Answers

The answer given by @Asperi should be avoided Apple says so in their documentation for StateObject.

You don’t call this initializer directly. Instead, declare a property with the @StateObject attribute in a View, App, or Scene, and provide an initial value.

Apple tries to optimize a lot under the hood, don't fight the system.

Just create an ObservableObject with a Published value for the parameter you wanted to use in the first place. Then use the .onAppear() to set it's value and SwiftUI will do the rest.

Code:

class SampleObject: ObservableObject {     @Published var id: Int = 0 }  struct MainView: View {     @StateObject private var sampleObject = SampleObject()          var body: some View {         Text("Identifier: \(sampleObject.id)")             .onAppear() {                 sampleObject.id = 9000             }     } } 
like image 170
Mark Avatar answered Oct 03 '22 10:10

Mark