Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a view with a stateobject as a parameter?

struct ProfileEditView: View {
    @ObservedObject var viewModel: UsersViewModel
    @StateObject var auth: Authenticator

    @State var showingImageEditor: Bool = false

    init(_ viewModel: UsersViewModel, _ auth: Authenticator) {
    
        self.viewModel = viewModel
        self.auth = auth
    
        UITableView.appearance().backgroundColor = UIColor.clear
        UITableViewCell.appearance().selectionStyle = .none
    }

    var body: some View { }
}

I am trying to manually intialize a view that takes a StateObject as a parameter. I am getting an error: Cannot assign to property: 'auth' is a get-only property. What is the proper way to write the initializer?

like image 442
seth.eeee Avatar asked Nov 20 '20 23:11

seth.eeee


People also ask

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.

How do I get the initial value of an observableobject?

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.

When does the @stateobject of a view get initialized?

That is because the @StateObject gets initialized after the View.init () and slightly before/after the body gets called. I tried a lot of different approaches on how to pass data from one view to another and came up with a solution that fits for simple and complex views / view models.

How do I call the initializer of a stateobject in iOS?

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.

How can we initialize a function without passing parameters?

So we can initialize it without passing parameters. greeting = "Hello, \ (name)!" <1> We update our initializer to accept an optional string with a default value of nil.


1 Answers

I can't fully reproduce your code without your definitions of Authenticator and UsersViewModel, but I got it to compile:

class UsersViewModel: ObservableObject {}
class Authenticator: ObservableObject {}

struct ProfileEditView: View {
    @ObservedObject var viewModel: UsersViewModel
    @StateObject var auth: Authenticator

    @State var showingImageEditor: Bool = false

    init(_ viewModel: ObservedObject<UsersViewModel>, _ auth: Authenticator) {

        _viewModel = viewModel
        _auth = StateObject(wrappedValue: auth)

        UITableView.appearance().backgroundColor = UIColor.clear
        UITableViewCell.appearance().selectionStyle = .none
    }

    var body: some View {
        Text("something")
    }
}

These are the key changes:

init(_ viewModel: ObservedObject<UsersViewModel>, _ auth: Authenticator) {
    _viewModel = viewModel
    _auth = StateObject(wrappedValue: auth)

If you don't understand my changes you should google

"swift property wrappers"

to get a better understanding of what property wrappers are and how to use them.

like image 66
Mozahler Avatar answered Nov 11 '22 15:11

Mozahler