SwiftUI:对同一变量使用不同的属性包装器

问题描述

iOS13中,我执行以下操作将视图绑定到模型:

class MyModel: ObservableObject {
    @Published var someVar: String = "initial value"
}

struct MyView: View {
    @Observedobject var model = MyModel()
    
    var body: some View {
        Text("the value is \(model.someVar)")
    }
}

iOS14中有一个名为@StateObject的新属性包装器,可以代替@Observedobject使用,我需要此代码段与iOS13和iOS14兼容,同时要利用iOS14的新功能,我该如何使用@StateObject来处理相同的变量?

解决方法

不同的属性包装器会生成不同类型的隐藏属性,因此您不能仅仅有条件地替换它们。这是一种可行方法的演示。

在Xcode 12 / iOS 14(部署目标13.6)上进行了测试

struct ContentView: View {
    var body: some View {
        if #available(iOS 14,*) {
            MyNewView()
        } else {
            MyView()
        }
    }
}

class MyModel: ObservableObject {
    @Published var someVar: String = "initial value"
}

@available(iOS,introduced: 13,obsoleted: 14,renamed: "MyNewView")
struct MyView: View {

    @ObservedObject var model = MyModel()

    var body: some View {
        CommonView().environmentObject(model)
    }
}

@available(iOS 14,*)
struct MyNewView: View {

    @StateObject var model = MyModel()

    var body: some View {
        CommonView().environmentObject(model)
    }
}

struct CommonView: View {
    @EnvironmentObject var model: MyModel

    var body: some View {
        Text("the value is \(model.someVar)")
    }
}