首页 > 解决方案 > 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相同的变量来做到这一点?

标签: iosswiftswiftui

解决方案


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

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

推荐阅读