如何在带有 Swift 的嵌套视图的 ForEach 语句中实现双向绑定?
How to implement a two-way binding in a ForEach statement with nested views with Swift?
我在 Foreach 语句中实现了双向绑定,似乎 工作正常:
struct ContentView: View {
@ObservedObject var dataManager: ContentViewModel
var body: some View {
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20){
ForEach($dataManager.data) { $item in
if item.status == true {
Button(item.tag){
item.status.toggle()
}
.foregroundColor(.white)
.background(Color.red)
} else {
Button(item.tag){
item.status.toggle()
}
.foregroundColor(.white)
.background(Color.blue)
}
}
}
}
}
}
问题 是当我必须使用一些嵌套视图时,例如:
struct ContentView: View {
@ObservedObject var dataManager: ContentViewModel
var body: some View {
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20){
ForEach($dataManager.data) { $item in
if item.status == true {
DetailView(dataManager: dataManager, item: item)
.foregroundColor(.white)
.background(Color.red)
} else {
Button(item.tag){
item.status.toggle()
}
.foregroundColor(.white)
.background(Color.blue)
}
}
}
}
}
}
和:
struct DetailView: View {
@ObservedObject var dataManager: ContentViewModel
var item: SMTTagBoardItem
var body: some View {
Button(item.tag){
item.status.toggle()
}
}
}
struct DetailView_Previews: PreviewProvider {
static var previews: some View {
DetailView(dataManager: ContentViewModel(), item: SMTTagBoardItem(id: UUID(), tag: "tag1", rank: 0, status: true))
}
}
我收到此错误:
Cannot use mutating member on immutable value: 'self' is immutable
行:
item.status.toggle()
如何在通过将值传递给嵌套视图的 ForEach 语句中实现双向绑定?
首先,不使用@ObservedObject,而是使用EnvironmentObject 和StateObject。
然后使用 @Binding var item
而不是 var item
。 (我认为dataManager.data是@Published变量)
ContentView
struct ContentView: View {
@StateObject var dataManager: ContentViewModel
var body: some View {
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20){
ForEach($dataManager.data) { $item in
if item.status == true {
DetailView(item: $item)
.environmentObject(dataManager)
.foregroundColor(.white)
.background(Color.red)
} else {
//more code
}
}
}
}
}
}
DetailView
struct DetailView: View {
@EnvironmentObject var dataManager: ContentViewModel
@Binding var item: SMTTagBoardItem
var body: some View {
Button(item.tag){
item.status.toggle()
}
}
}
我在 Foreach 语句中实现了双向绑定,似乎 工作正常:
struct ContentView: View {
@ObservedObject var dataManager: ContentViewModel
var body: some View {
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20){
ForEach($dataManager.data) { $item in
if item.status == true {
Button(item.tag){
item.status.toggle()
}
.foregroundColor(.white)
.background(Color.red)
} else {
Button(item.tag){
item.status.toggle()
}
.foregroundColor(.white)
.background(Color.blue)
}
}
}
}
}
}
问题 是当我必须使用一些嵌套视图时,例如:
struct ContentView: View {
@ObservedObject var dataManager: ContentViewModel
var body: some View {
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20){
ForEach($dataManager.data) { $item in
if item.status == true {
DetailView(dataManager: dataManager, item: item)
.foregroundColor(.white)
.background(Color.red)
} else {
Button(item.tag){
item.status.toggle()
}
.foregroundColor(.white)
.background(Color.blue)
}
}
}
}
}
}
和:
struct DetailView: View {
@ObservedObject var dataManager: ContentViewModel
var item: SMTTagBoardItem
var body: some View {
Button(item.tag){
item.status.toggle()
}
}
}
struct DetailView_Previews: PreviewProvider {
static var previews: some View {
DetailView(dataManager: ContentViewModel(), item: SMTTagBoardItem(id: UUID(), tag: "tag1", rank: 0, status: true))
}
}
我收到此错误:
Cannot use mutating member on immutable value: 'self' is immutable
行:
item.status.toggle()
如何在通过将值传递给嵌套视图的 ForEach 语句中实现双向绑定?
首先,不使用@ObservedObject,而是使用EnvironmentObject 和StateObject。
然后使用 @Binding var item
而不是 var item
。 (我认为dataManager.data是@Published变量)
ContentView
struct ContentView: View {
@StateObject var dataManager: ContentViewModel
var body: some View {
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20){
ForEach($dataManager.data) { $item in
if item.status == true {
DetailView(item: $item)
.environmentObject(dataManager)
.foregroundColor(.white)
.background(Color.red)
} else {
//more code
}
}
}
}
}
}
DetailView
struct DetailView: View {
@EnvironmentObject var dataManager: ContentViewModel
@Binding var item: SMTTagBoardItem
var body: some View {
Button(item.tag){
item.status.toggle()
}
}
}