在这里构建我的第一个应用程序,所以我很好奇我是否正在以正确的方式进行操作。
我的应用程序允许用户在创建费用对象之前创建帐户和类别,这将允许用户选择要应用到费用的帐户和类别。
如何在单个视图中从两个实体(帐户和类别)中获取?
我尝试将所有属性都包括在Expenses实体下,但是似乎在保存时,它会在ExpenseList视图中创建一个新的Expense。
我有3个CoreData实体和2个选择器(用于类别和帐户)
费用
类别
帐户
import SwiftUI
import CoreData
struct ExpenseDetail: View {
@FetchRequest(
entity: Categories.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Categories.categoryName, ascending: true)
]
)
private var result: FetchedResults<Categories>
var logToEdit: Expenses?
@Environment(\.managedObjectContext) var context
@State var name: String = ""
@State var amount: String = ""
@State var category: String = ""
@State var date: Date = Date()
@State var account: String = ""
@State var isMonthly: Bool = false
var currencyFormatter: NumberFormatter = {
let f = NumberFormatter()
f.numberStyle = .currency
return f
}()
@Environment(\.presentationMode) var presentationMode
var body: some View {
NavigationView {
Form{
TextField("Expense Name", text: $name)
Section{
HStack{
TextField("$\(amount)", text: $amount)
.keyboardType(.decimalPad)
.textFieldStyle(PlainTextFieldStyle())
.disableAutocorrection(true).multilineTextAlignment(.leading)
}
DatePicker(selection: $date, displayedComponents: .date) {
Text("Date")
}.onAppear{self.hideKeyboard()}
Picker(selection: $category, label: Text("Category")) {
ForEach(result) { (log: Categories) in
Text(log.categoryName ?? "No Category").tag(log.categoryName)
}
}
Picker(selection: $account, label: Text("Account")) {
ForEach(result) { (log: Categories) in
self.Print("\(log.categoryName ?? "")")
Button(action: {
// TODO: Implement Edit
}) {
Text(log.categoryName!.capitalized).tag(self.category)
}
}
}
Toggle(isOn: $isMonthly) {
Text("Monthly Expense")
}.toggleStyle(CheckboxToggleStyle())
}
Section{
Button(action: {
onSaveTapped()
}) {
HStack {
Spacer()
Text("Save")
Spacer()
}
}
}
Section{
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
HStack {
Spacer()
Text("Cancel").foregroundColor(.red)
Spacer()
}
}
}
}.navigationBarTitle("Add Expense")
}
}
private func onSaveTapped() {
let expenseLog: Expenses
if let logToEdit = self.logToEdit {
expenseLog = logToEdit
} else {
expenseLog = Expenses(context: self.context)
expenseLog.expenseId = UUID()
}
expenseLog.expenseName = self.name
expenseLog.expenseCategory = self.category
print("\(expenseLog.expenseName ?? "") category Picker: \(self.category)")
print("\(expenseLog.expenseName ?? "") ExpenseCategory: \(expenseLog.expenseCategory!)")
expenseLog.expenseCost = Double(self.amount) ?? 0
print("\(expenseLog.expenseName ?? "") Amount: \(self.amount)")
print("\(expenseLog.expenseName ?? "")ExpenseCost: \(expenseLog.expenseCost)")
expenseLog.expenseDate = self.date
expenseLog.expenseAccount = self.account
expenseLog.expenseIsMonthly = self.isMonthly
do {
try context.save()
} catch let error as NSError {
print(error.localizedDescription)
}
self.presentationMode.wrappedValue.dismiss()
}
}
ExpenseList代码,如果需要:
NavigationView{
if #available(iOS 14.0, *) {
List{
ForEach(result) { (log: Expenses) in
self.Print("\(log.expenseName ?? "") expenseCost: \(log.expenseCost)")
self.Print("\(log.expenseName ?? "") amountText: \(log.amountText)")
Button(action: {
// TODO: Implement Edit
}) {
HStack(spacing: 16) {
VStack(alignment: .leading, spacing: 8) {
Text(log.nameText).font(.headline)
Text(log.dateText).font(.caption)
}
Spacer()
VStack(alignment: .trailing, spacing: 8){
Text(log.amountText).font(.headline)
Text(log.expenseAccount?.capitalized ?? "").font(.caption)
Text(log.expenseCategory ?? "No Category")
}
}
.padding(.vertical, 2)
}
}.onDelete(perform: onDelete)
}.navigationTitle("Expense List")
.navigationBarItems(trailing:
Button(action: {
// toggles the value of our bool from false to true,
// which will present our sheet.
self.addExpense.toggle()
}, label: {
Image(systemName: "plus.circle.fill")
})
.sheet(isPresented: $addExpense) {
ExpenseDetail()
}
)
} else {
// Fallback on earlier versions
}
}
}
用于保存类别的代码:
private func onSaveTapped() {
let log: Categories
if let logToEdit = self.logToEdit {
log = logToEdit
} else {
log = Categories(context: self.context)
}
log.categoryName = self.category
do {
try context.save()
} catch let error as NSError {
print(error.localizedDescription)
}
}
}