提问者:小点点

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


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

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

所以我想把状态从单元传递到主模型,并在那里进行反应。例如发送请求。


共2个答案

匿名用户

您需要在settingscell中将ison声明为@binding

@state只能用于在视图本身内初始化的属性,并且必须始终为private。如果希望传入一个值,该值应在视图更改时更新该视图,但该值是在视图外部创建的,则需要使用绑定

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

如果您的目标是IOS14,并且希望在视图中创建模型,则可以使用@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)
        }
    }
}

匿名用户

绑定用于父视图“拥有”数据的情况--即父视图持有真值的来源--并且需要子视图对其进行更新:

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