swift 如何初始化一个视图并将一个状态对象作为参数?

ht4b089n  于 2023-03-16  发布在  Swift
关注(0)|答案(2)|浏览(131)
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 { }
}

我试图手动初始化一个以StateObject为参数的视图。我收到一个错误:Cannot assign to property: 'auth' is a get-only property。编写初始化器的正确方法是什么?

46qrfjad

46qrfjad1#

如果没有AuthenticatorUsersViewModel的定义,我无法完全重现您的代码,但我得到了它的编译:

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")
    }
}

以下是主要变化:

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

如果你不明白我的变化,你应该谷歌
“swift属性 Package 器”
以更好地理解什么是属性 Package 器以及如何使用它们。

nmpmafwu

nmpmafwu2#

除了“公认答案”之外,还有一个很好的例子,可以让每个人重现错误,并了解如何避免它。
考虑到View中有一个viewModel带有属性 Package 器@StateObject,只要View中没有私有属性,就不需要在构造器中初始化StateObject(wrappedValue: ...),我们来看一个例子:

class MyViewModel: ObservableObject {}

class MyView: View {
   @StateObject var viewModel: MyViewModel
}

上面的示例只需使用以下命令即可运行:

MyView(viewModel: MyViewModel())

但是如果我们将私有属性添加到View

class MyView: View {
   @StateObject var viewModel: MyViewModel
   // `test` will produce the protection level error
   private var test = false
}

我们前面的示例MyView(viewModel: MyViewModel())现在将产生以下错误:

  • 由于“private”保护级别,无法访问初始值设定项 *

因此,请考虑一下为什么要在View private中声明一个属性,也许可以将其移动到ViewModel中,这样就可以解决这个问题,从而利用依赖注入原理。

相关问题