SwiftUI / 在两个模型之间组合传递数据

Posted

技术标签:

【中文标题】SwiftUI / 在两个模型之间组合传递数据【英文标题】:SwiftUI / Combine Pass data between two models 【发布时间】:2021-03-19 12:15:50 【问题描述】:

我对如何在两个模型之间传递数据有疑问。

struct SettingsCell: View 
    @State var isOn: Bool

    var body: some View 
        Toggle(name, isOn: $isOn)
    


class SettingsModel: ObservableObject 
    @Published var someValue: Bool = false


struct SettingsView: View 
    @ObservedObject var model = SettingsModel()

    var body: some View 
        List 
            SettingsCell(isOn: model.someValue)
        
    

所以我想将 isOn 状态从单元传递到主模型,然后在那里做出反应。例如发送请求。

【问题讨论】:

【参考方案1】:

您需要在SettingsCell 中将isOn 声明为@Binding

@State 只能用于在View 内部初始化的属性,并且必须始终为private。如果您要传入一个值,该值应在 View 更改时更新,但该值是在 View 之外创建的,则需要使用 Binding

要注意的另一件非常重要的事情是@ObservedObjects 必须始终注入Views,您不能在视图本身内初始化它们。这是因为每当更新 @ObservedObject 时,它都会更新视图本身,因此如果您在视图中初始化对象,每当对象更新视图时,视图都会创建一个新的 @ObservedObject,因此您的更改不会从视图持久化到模型。

如果您的目标是 ios 14 并想在视图中创建模型,您可以改用 @StateObject

struct SettingsCell: View 
    @Binding private var isOn: Bool

    init(isOn: Binding<Bool>) 
        self._isOn = isOn
    

    var body: some View 
        Toggle(name, isOn: $isOn)
    


class SettingsModel: ObservableObject 
    @Published var someValue: Bool = false


struct SettingsView: View 
    @ObservedObject private var model: SettingsModel

    init(model: SettingsModel) 
        self.model = model
    

    var body: some View 
        List 
            SettingsCell(isOn: $model.someValue)
        
    

【讨论】:

感谢您提供更详细的描述。将了解如何使用 ObservedObject 和 StateObject【参考方案2】:

Binding 用于数据由父视图“拥有”的情况 - 即父视图拥有事实来源 - 并且需要子视图更新它:

struct SettingsCell: View 
    @Binding var isOn: Bool // change to Binding

    var body: some View 
        Toggle(name, isOn: $isOn)
    


struct SettingsView: View 
    // unrelated, but better to use StateObject
    @StateObject var model = SettingsModel() 

    var body: some View 
        List 
            // pass the binding by prefixing with $
            SettingsCell(isOn: $model.someValue)
        
    

【讨论】:

以上是关于SwiftUI / 在两个模型之间组合传递数据的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:如何将 NSManagedObjectContext 传递到多个视图模型中

将数据从模型传递到 SwiftUI 中的视图

如何将数据从父模型类传递到 SwiftUI 中的子视图

SwiftUI 为啥不能在视图之间传递发布者?

在 2 个页面 SwiftUI 之间传递状态

在 SwiftUi 中的视图之间传递列表