Я пытаюсь отобразить массив структур 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
Программируем под IOS
1735491857
Anonymous
Я пытаюсь отобразить массив структур Word в дочерних TextFields, используя архитектуру MVVM, передав привязку к структуре Word дочернему элементу. Существует кнопка для вставки нового пустого слова Word в массив в позиции 0, который заполняется через цикл ForEach в дочерние элементы. Однако, если текстовое поле останется пустым и фокус изменится, я хотел бы удалить этот элемент из родительского массива. Я передал функцию для этого в родительском цикле ForEach. Наконец, в модификаторе OnChange дочернего элемента я вызываю эту функцию, если oldValue равен тому, который потерял фокус, и isEmpty имеет значение true. Но это приводит к фатальной ошибке: Индекс вне диапазона.
При отладке кажется, что код успешно удалил нужный элемент из массива, и что ошибка возникает при последующих проходах цикл ForEach перебирает массив слов. Как я могу это исправить? Весь мой код приведен ниже.
[b]Родительский код[/b]
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()
}
}
}
}
[b]Дочерний код[/b]
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 }
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79315993/fatal-error-index-out-of-range-when-adding-and-removing-from-array-with-mvvm[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия