Я пытаюсь отобразить массив структур Word в дочерних TextFields, используя архитектуру MVVM, передав привязку к структуре Word дочернему элементу. Существует кнопка для вставки нового пустого слова Word в массив в позиции 0, который заполняется через цикл ForEach в дочерние элементы. Однако, если текстовое поле останется пустым и фокус изменится, я хотел бы удалить этот элемент из родительского массива. Я передал функцию для этого в родительском цикле ForEach. Наконец, в модификаторе OnChange дочернего элемента я вызываю эту функцию, если oldValue равен тому, который потерял фокус, и isEmpty имеет значение true. Но это приводит к фатальной ошибке: Индекс вне диапазона.
При отладке кажется, что код успешно удалил нужный элемент из массива, и что ошибка возникает при последующих проходах цикл ForEach перебирает массив слов. Как я могу это исправить? Весь мой код приведен ниже.
Родительский код
struct Word: Identifiable, Equatable {
var id: String
var word: String
var definition: String?
init(_ word: String, definition: String?) {
self.word = word
self.definition = definition
self.id = UUID().uuidString
}
static func ==(lhs: Word, rhs: Word) -> Bool {
return lhs.id == rhs.id
}
}
class CardViewModel: ObservableObject {
var word: Binding
@Published var loading: Bool = false
init(word: Binding) {
self.word = word
}
}
enum Focusable: Hashable {
case none
case row(id: String)
}
struct CardView: View {
@ObservedObject var vm: CardViewModel
@FocusState var focused: Focusable?
let onEmpty: () -> Void // delete the word!
var body: some View {
VStack(spacing: 0) {
HStack { TextField("", text: vm.word.word)
.font(.title)
.focused($focused, equals: .row(id: vm.word.id))
; Spacer() }
if vm.loading == true {
Text("Loading...")
.frame(maxWidth: .infinity, alignment: .leading)
}
if let definition = vm.word.definition.wrappedValue {
Text(definition)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.onChange(of: focused) { oldValue, newValue in
if oldValue == .row(id: vm.word.wrappedValue.id) && vm.word.wrappedValue.word.isEmpty {
onEmpty()
}
}
}
}
Дочерний код
import SwiftUI
class StudyViewModel: ObservableObject {
@Published var words: [Word] =
[
Word("sonder", definition: "The realization that each passerby has a life as vivid as your own."),
[...]
]
}
struct StudyView: View {
@Namespace private var namespace
@State private var cardsHeight: CGFloat = 0
@FocusState var focusedReminder: Focusable?
@StateObject var vm: StudyViewModel = StudyViewModel()
var body: some View {
VStack(spacing: 20) {
HStack {
Image(systemName: "gear")
Spacer()
Button {
// add action here
addWordCard()
} label: {
Image(systemName: "plus.circle")
}
.tint(.black)
}
.font(.title)
ScrollView {
VStack(spacing: 20) {
ForEach($vm.words) { $word in
CardView(vm: CardViewModel(word: $word), focused: _focusedReminder) {
deleteWord($word.wrappedValue)
}
}
}
}
}
}
}
// Helper Functions
extension StudyView {
private func addWordCard() {
withAnimation(.spring) {
let new_word = Word("", definition: nil)
vm.words.insert(new_word, at: 0)
focusedReminder = .row(id: new_word.id)
}
}
private func deleteWord(_ word: Word) {
withAnimation(.spring) {
// vm.words.removeAll { $0.id == word.id }
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... -with-mvvm
Неустранимая ошибка: индекс выходит за пределы диапазона при добавлении и удалении из массива с помощью MVVM. ⇐ IOS
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Индекс вектора C++ выходит за пределы диапазона при определенных условиях [закрыто]
Anonymous » » в форуме C++ - 0 Ответы
- 70 Просмотры
-
Последнее сообщение Anonymous
-
-
-
IndexError: индекс списка выходит за пределы диапазона при доступе по ssh [закрыто]
Anonymous » » в форуме Python - 0 Ответы
- 28 Просмотры
-
Последнее сообщение Anonymous
-