Я использую архитектуру MVVM со SwiftUI.
Я пытаюсь реорганизовать свой код, чтобы использовать ForEach() в моем представлении для отображения ряда подпредставлений, которые имеют одинаковый базовый формат, строку (задавая вопрос) и кнопку, которую нужно нажать, чтобы отобразить лист для ввода значения .
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 элемента Question массива вопросов изменяется на true, оно фактически не изменяет сам массив, и поэтому издатель не обновляет представление.
Как мне это исправить, пожалуйста?
Я все еще изо всех сил пытаюсь понять SwiftUI и Combine, поэтому любые указатели будут с благодарностью получены.
Вы не можете «связывать» ObservableObjects. Вы должны Наблюдать за ними напрямую.
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()
}
}
Спасибо. Имеет смысл. Попробую во вторник и тогда отмечу как правильное.