如何将 SwiftUI 视图绑定到数组中元素的属性
How to bind a SwiftUI view to properties of an element in an array
我在 SwiftUI 中使用 MVVM 架构。
我正在尝试重构我的代码以在我的视图中使用 ForEach() 来显示多个子视图,这些子视图都具有相同的基本格式、一个字符串(提出问题)和一个按下按钮以显示sheet 输入值。
struct EntryView: View {
@ObservedObject var viewModel = EntryViewModel()
var body: some View {
VStack (spacing: 50) {
ForEach(viewModel.questions.indices) { index in
HStack (spacing: 50) {
Text(viewModel.questions[index].text)
.sheet(isPresented: $viewModel.questions[index].sheetIsPresented,
content: {
viewModel.questions[index].sheet
})
Button(action: {
viewModel.questions[index].sheetIsPresented = true
}, label: {
Text("Enter")
})
}
}
}
}
}
class EntryViewModel: ObservableObject {
@Published var questions: [Question] = []
@Published var firstQuestion = Question()
@Published var secondQuestion = Question()
init() {
questions.append(firstQuestion)
questions.append(secondQuestion)
}
}
class Question: ObservableObject {
@Published var sheetIsPresented = false
let text = "Foo"
var sheet = AnyView(InitialView())
}
问题在于,尽管按钮更改了数组中正确索引处正确元素中的正确 属性,但这不会导致视图更新。
我知道这是因为当问题数组的问题元素的 sheetIsPresented 属性 更改为 true 时,它实际上并没有改变数组本身,所以发布者没有更新视图。
请问我该如何解决?
我仍在努力了解 SwiftUI 和 Combine,因此非常感谢收到任何指示。
您不能“链接”ObservableObject。你必须直接观察它们。
import SwiftUI
struct EntryView: View {
@ObservedObject var viewModel = EntryViewModel()
var body: some View {
VStack (spacing: 50) {
ForEach(viewModel.questions.indices) { index in
SingleEntryView(viewModel: viewModel.questions[index])
}
}
}
}
struct SingleEntryView: View {
@ObservedObject var viewModel: Question
var body: some View {
HStack (spacing: 50) {
Text(viewModel.text)
.sheet(isPresented: $viewModel.sheetIsPresented,
content: {
viewModel.sheet
})
Button(action: {
viewModel.sheetIsPresented = true
}, label: {
Text("Enter")
})
}
}
}
class EntryViewModel: ObservableObject {
@Published var questions: [Question] = []
@Published var firstQuestion = Question()
@Published var secondQuestion = Question()
init() {
questions.append(firstQuestion)
questions.append(secondQuestion)
}
}
class Question: ObservableObject {
@Published var sheetIsPresented = false
let text = "Foo"
var sheet = AnyView(Text("Sheet"))
}
struct EntryView_Previews: PreviewProvider {
static var previews: some View {
EntryView()
}
}
我在 SwiftUI 中使用 MVVM 架构。
我正在尝试重构我的代码以在我的视图中使用 ForEach() 来显示多个子视图,这些子视图都具有相同的基本格式、一个字符串(提出问题)和一个按下按钮以显示sheet 输入值。
struct EntryView: View {
@ObservedObject var viewModel = EntryViewModel()
var body: some View {
VStack (spacing: 50) {
ForEach(viewModel.questions.indices) { index in
HStack (spacing: 50) {
Text(viewModel.questions[index].text)
.sheet(isPresented: $viewModel.questions[index].sheetIsPresented,
content: {
viewModel.questions[index].sheet
})
Button(action: {
viewModel.questions[index].sheetIsPresented = true
}, label: {
Text("Enter")
})
}
}
}
}
}
class EntryViewModel: ObservableObject {
@Published var questions: [Question] = []
@Published var firstQuestion = Question()
@Published var secondQuestion = Question()
init() {
questions.append(firstQuestion)
questions.append(secondQuestion)
}
}
class Question: ObservableObject {
@Published var sheetIsPresented = false
let text = "Foo"
var sheet = AnyView(InitialView())
}
问题在于,尽管按钮更改了数组中正确索引处正确元素中的正确 属性,但这不会导致视图更新。
我知道这是因为当问题数组的问题元素的 sheetIsPresented 属性 更改为 true 时,它实际上并没有改变数组本身,所以发布者没有更新视图。
请问我该如何解决?
我仍在努力了解 SwiftUI 和 Combine,因此非常感谢收到任何指示。
您不能“链接”ObservableObject。你必须直接观察它们。
import SwiftUI
struct EntryView: View {
@ObservedObject var viewModel = EntryViewModel()
var body: some View {
VStack (spacing: 50) {
ForEach(viewModel.questions.indices) { index in
SingleEntryView(viewModel: viewModel.questions[index])
}
}
}
}
struct SingleEntryView: View {
@ObservedObject var viewModel: Question
var body: some View {
HStack (spacing: 50) {
Text(viewModel.text)
.sheet(isPresented: $viewModel.sheetIsPresented,
content: {
viewModel.sheet
})
Button(action: {
viewModel.sheetIsPresented = true
}, label: {
Text("Enter")
})
}
}
}
class EntryViewModel: ObservableObject {
@Published var questions: [Question] = []
@Published var firstQuestion = Question()
@Published var secondQuestion = Question()
init() {
questions.append(firstQuestion)
questions.append(secondQuestion)
}
}
class Question: ObservableObject {
@Published var sheetIsPresented = false
let text = "Foo"
var sheet = AnyView(Text("Sheet"))
}
struct EntryView_Previews: PreviewProvider {
static var previews: some View {
EntryView()
}
}