swift - 通过关系列出 CoreData 对象
问题描述
我在没有 CoreData 关系(多次获取)的情况下工作,但我想到我可能应该在这些实体之间实现关系,这样我就可以从单个实体中获取所有属性。
当我直接从 Accounts 实体中为我的 AccountsList.swift 获取 accountNames(以创建帐户)时,它工作得很好,但是当我尝试通过关系(originAccounts)调用它们时,它不会在列表中显示任何内容。类别选择器的相同问题。
我有 3 个 CoreData 实体和两个 Picker(用于类别和帐户)
花费
- 费用帐户:字符串
- 费用类别:字符串
- 费用成本:双倍
- 费用日期:日期
- 费用ID:UUID
- 费用是每月:布尔
- 费用名称:字符串
类别
- 类别名称:字符串
账户
- 帐户名:字符串
费用与帐户和类别具有多对一的关系
import SwiftUI
import CoreData
struct ExpenseDetail: View {
@Environment(\.managedObjectContext) var context
@Environment(\.presentationMode) var presentationMode
@FetchRequest(fetchRequest: Expenses.expensesList)
var results: FetchedResults<Expenses>
var logToEdit: Expenses?
@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
}()
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(results) { (log: Expenses) in
Text(log.originCategories?.categoryName ?? "No Category").tag(log.originCategories?.categoryName)
}
}
Picker(selection: $account, label: Text("Account")) {
ForEach(results) { (log: Expenses) in
Text(log.originAccounts?.accountName ?? "No Account").tag(log.originAccounts?.accountName)
}
}
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.originCategories?.categoryName = self.category
expenseLog.expenseCost = Double(self.amount) ?? 0
expenseLog.expenseDate = self.date
expenseLog.originAccounts?.accountName = self.account
print("\(self.account ?? "NoAccountValue")")
expenseLog.expenseIsMonthly = self.isMonthly
do {
try context.save()
} catch let error as NSError {
print(error.localizedDescription)
}
self.presentationMode.wrappedValue.dismiss()
}
}
#if canImport(UIKit)
extension View {
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
#endif
struct ExpenseDetail_Previews: PreviewProvider {
static var previews: some View {
ExpenseDetail()
}
}
struct CheckboxToggleStyle: ToggleStyle {
func makeBody(configuration: Configuration) -> some View {
return HStack {
configuration.label
Spacer()
Image(systemName: configuration.isOn ? "checkmark.square" : "square")
.resizable()
.frame(width: 22, height: 22)
.onTapGesture { configuration.isOn.toggle() }
}
}
}
如果需要,费用列表获取详细信息
static var expensesList: NSFetchRequest<Expenses> {
let request: NSFetchRequest<Expenses> = Expenses.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "expenseName", ascending: true)]
return request
}
解决方案
推荐阅读
- javascript - 如何在 Antd 中使用嵌套的单选按钮组?
- android - Android RecyclerView 滚动到特定单词
- node.js - Schema Generator 无法确定 DTO 中自定义对象的 GraphQL 输出类型
- python - 数 a 被称为关于 n 的乘法逆
- elixir - 我的 Comeonin.bcrypt 密码散列代码有问题
- java - 不同的线程获得相同的实体并且看不到彼此的变化
- c - libgit2 git_checkout_head 和 GIT_CHECKOUT_SAFE 对工作目录不做任何事情
- excel - 用VBA在单元格中写一个excel公式
- reactjs - 反应材料 UI 网格
- visual-studio - VS Studio Community 2019:非解文件代码格式化时出现异常