#swift #swiftui
#swift #swiftui
Вопрос:
Я запускаю функцию для заполнения списка расходов. Мне нужно запустить функцию для заполнения списка с помощью .onAppear(perform: fetchRows)
, чтобы список обновлялся, как только появляется представление.
Xcode не нравится тот факт, что я запускаю функцию для заполнения списка расходов. Как я могу заставить это работать? Есть ли лучший способ сделать это?
@State var expensesList: [ExpensesList]?
var body: some View {
NavigationView{
VStack{
if expensesList != nil{
List{
ForEach(self.expensesList!) { <-- Type '() -> ()' cannot conform to 'View'; only struct/enum/class types can conform to protocols
(log: ExpensesList) in {
Button(action: {
self.editExpense = log
})
ExpenseRow(name: log.expense, date: log.date, amount: log.cost, account: log.account)
}
}.onDelete(perform: onDelete)
}
}
}.navigationTitle("Expense List")
struct ExpensesList: Identifiable, Equatable {
let id: UUID
let expense: String
let cost: Double
let account: String
let date: Date
}
func fetchRows(){
Expenses.fetchAllExpensesInDateRange(context: self.context) { (results) in
guard !results.isEmpty else { return }
self.expensesList = results.map({ (result) -> ExpensesList in
print(result.id,result.expenseName,result.expenseCost, result.expenseAccount, result.expenseDate)
return ExpensesList(id: result.id, expense: result.expenseName, cost: result.expenseCost, account: result.expenseAccount, date: result.expenseDate)
})
}
}
Таблица, которую я использую для редактирования расходов, находится здесь . Как вы можете видеть, я использую объект основных данных под названием Расходы для хранения моих объектов расходов.
.sheet(item: $editExpense, onDismiss: {
self.editExpense = nil
})
{
(log: Expenses) in
ExpenseDetail(
context: self.context,
editExpense: log,
name: log.expenseName ?? "",
amount: String(log.expenseCost),
category: log.expenseCategory ?? "",
date: log.expenseDate ?? Date(),
account: log.expenseAccount ?? "",
isMonthly: log.expenseIsMonthly
).environment(.managedObjectContext, self.context)
}
Ответ №1:
У вас есть дополнительный {
after (log: ExpensesList) in {
, а у вашего Button
нет content
параметра.
Вместо этого попробуйте следующее (я предполагаю, что ExpenseRow
это должно быть content
из кнопки):
ForEach(self.expensesList!) { log in
Button(action: {
self.editExpense = log
}) {
ExpenseRow(name: log.expense, date: log.date, amount: log.cost, account: log.account)
}
}
Обратите внимание, что в SwiftUI 2 вы можете использовать операторы потока управления (например if-let
) непосредственно в @ViewBuilder
блоках:
if let expensesList = expensesList {
List {
ForEach(expensesList) { log in
// ...
}
}
}
Комментарии:
1. Спасибо @pawello2222! Это решило мою ошибку сборки, но я забыл включить это self.editExpense нужна статья расходов из моих основных данных. Я думаю, это немного усложняет задачу, потому что мне нужно каким-то образом преобразовать мой объект ExpensesList в объект Expenses .
2. @nastri83 Я понимаю, но это похоже на другой вопрос. Я рекомендую вам создать еще один пост с вашей новой проблемой.