Ошибка привязки текстового поля к объекту в массиве - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть массив объектов SplitItem, которые я пытаюсь сделать для l oop и показать текстовое поле. Я получаю сообщение об ошибке. Для этого кода используется неразрешенный идентификатор '$ item',

import SwiftUI

struct ContentView: View {

    @State var selectedAccount:Int = -1
    @State var splitItems:[SplitItem] = [
        SplitItem(account: 0, amount: "1.00", ledger: .Accounts),
        SplitItem(account: 0, amount: "2.00", ledger: .Accounts),
        SplitItem(account: 0, amount: "3.00", ledger: .Budgets),
        SplitItem(account: 0, amount: "4.00", ledger: .Budgets)
    ]

    var body: some View {
        VStack {
            ForEach(self.splitItems) { item in
                TextField(item.amount, text: $item.amount)
            }
        }.frame(maxWidth: .infinity, maxHeight: .infinity)
    }

}

struct SplitItem: Identifiable {
    @State var id:UUID = UUID()
    @State var account:Int
    @State var amount:String
    @State var ledger:LedgerType
}
enum LedgerType:Int {case Accounts=0,Budgets=1}

, если я изменяю text: $item.amount на text: item.$amount, он компилируется, но получающееся текстовое поле не позволяет мне его изменить. То же самое, если я изменяю для l oop на индексы и пытаюсь выполнить привязку на основе индекса,

ForEach(self.splitItems.indices) { index in
    TextField(self.splitItems[index].amount, text: self.$splitItems[index].amount)
}

, у него нет проблем с отображением Text(item.amount), только когда я пытаюсь выполнить привязку, иметь проблему. Я думаю, что это как-то связано с массивом, потому что, если я пытаюсь привязать отдельный разделенный элемент, а не массив, к текстовому полю, он работает просто отлично. Я также попытался создать подпредставление с текстовым полем и вызвать его с foreach l oop, но я получил ту же ошибку.

также это swiftui для Ma c, а не iOS.

1 Ответ

0 голосов
/ 28 февраля 2020

Это не Ма c и не iOS, специфицированные c.

Прежде всего, используйте состояние в качестве единственного источника истины только для данного представления.

В вашем случае переместите данные и бизнес-логику c в вашу модель, представленную некоторым ObservableObject. В вашем View используйте оболочку свойства @ObservedObject.

Ваша (упрощенная) структура данных и модель могут быть определены как

struct Item: Identifiable {
    let id = UUID()
    var txt = ""
}

class Model: ObservableObject {
    @Published var items = [Item(txt: "alfa"), Item(txt: "beta")]
}

Теперь вы готовы использовать эту модель в View. Когда значение состояния изменяется, представление делает его недействительным и повторно вычисляет тело, и то же самое верно для ObservedObject.

struct ContentView: View {
    @ObservedObject var model = Model()
    var body: some View {
        VStack {
            ForEach(model.items.indices) { idx in
                VStack {
                    Text(self.model.items[idx].txt.capitalized).bold()
                    TextField("label", text: self.$model.items[idx].txt).frame(idealWidth: 200)
                }
            }
        }.frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...