SwiftUI / 合并两个模型之间的传递数据
SwiftUI / Combine Pass data between two models
我对如何在两个模型之间传递数据有疑问。
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 状态从单元格传递到主模型,并在那里做出反应。例如发送请求。
您需要在 SettingsCell
中将 isOn
声明为 @Binding
。
@State
只能用于在 View
内部初始化的属性,并且必须始终为 private
。如果要传入一个值,该值应在 View
更改时更新,但该值是在 View
之外创建的,则需要使用 Binding
.
另一个需要注意的非常重要的事情是 @ObservedObject
s 必须始终注入到 View
s 中,你不能在视图本身内部初始化它们。这是因为每当更新 @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)
}
}
}
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)
}
}
}
我对如何在两个模型之间传递数据有疑问。
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 状态从单元格传递到主模型,并在那里做出反应。例如发送请求。
您需要在 SettingsCell
中将 isOn
声明为 @Binding
。
@State
只能用于在 View
内部初始化的属性,并且必须始终为 private
。如果要传入一个值,该值应在 View
更改时更新,但该值是在 View
之外创建的,则需要使用 Binding
.
另一个需要注意的非常重要的事情是 @ObservedObject
s 必须始终注入到 View
s 中,你不能在视图本身内部初始化它们。这是因为每当更新 @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)
}
}
}
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)
}
}
}