【发布时间】:2021-05-06 20:04:24
【问题描述】:
我有一个条目列表,每个条目都附有日期。我只想在日期发生变化时才显示日期。我首先在 iOS 14.4 中开发了这个软件,导致视图不可变错误。这是因为我正在存储和更改输入日期的副本。
现在在 iOS 14.5 版本中,我看不到不可变错误。但是我的软件还是不行。如果您运行代码并在控制台中查看,您会注意到 Xcode 两次检查了我的六个条目:第一次始终为真(显示日期),第二次始终为假(不显示日期)。为什么?
在我的实际代码中,我在此示例代码中使用 Date 类型的日期而不是字符串。在我的实际代码中,操作挂起,因为它通过我的函数 checkDate 无休止地循环(比条目数多很多倍)。 Date 类型的日期是否包括导致比较失败的时间?
如果日期与上一个条目相同,是否有更好的方法来防止显示日期?
struct KitchenItem: Codable, Identifiable {
var id = UUID()
var item: String
var itemDate: String
var itemCost: Double
}
class Pantry: ObservableObject {
@Published var oldDate: String = ""
@Published var kitchenItem: [KitchenItem]
init() {
self.kitchenItem = []
let item0 = KitchenItem(item: "String Beans", itemDate: "1/13/2021", itemCost: 4.85)
self.kitchenItem.append(item0)
let item1 = KitchenItem(item: "Tomatoes", itemDate: "1/22/2021", itemCost: 5.39)
self.kitchenItem.append(item1)
let item2 = KitchenItem(item: "Bread", itemDate: "1/22/2021", itemCost: 4.35)
self.kitchenItem.append(item2)
let item3 = KitchenItem(item: "Corn", itemDate: "3/18/2021", itemCost: 2.75)
self.kitchenItem.append(item3)
let item4 = KitchenItem(item: "Peas", itemDate: "3/18/2021", itemCost: 7.65)
self.kitchenItem.append(item4)
let item5 = KitchenItem(item: "Ice Cream", itemDate: "4/12/2021", itemCost: 7.95)
self.kitchenItem.append(item5)
}
}
struct ContentView: View {
@ObservedObject var pantry: Pantry = Pantry()
var body: some View {
LazyVStack (alignment: .leading) {
Text("Grandma's Food Pantry")
.font(.title)
.fontWeight(.bold)
.padding(.top, 36)
.padding(.leading, 36)
.padding(.bottom, 30)
ForEach(0..<pantry.kitchenItem.count, id: \.self) { item in
VStack (alignment: .leading) {
showRow(item: item)
}
}
}
}
}
struct showRow: View {
@ObservedObject var pantry: Pantry = Pantry()
var item: Int
var body: some View {
// don't show the date if is the same as the previous entry
let newDate = pantry.kitchenItem[item].itemDate
if checkDate(newDate: newDate) == true {
Text("\n\(newDate)")
.font(.title2)
.padding(.leading, 10)
}
HStack {
Text("\(pantry.kitchenItem[item].item)")
.padding(.leading, 50)
.frame(width: 150, alignment: .leading)
Text("\(pantry.kitchenItem[item].itemCost, specifier: "$%.2f")")
}
}
func checkDate(newDate: String) -> (Bool) {
print(" ")
print("new date = \(newDate)")
if newDate == pantry.oldDate {
print("false: don't show the date")
return false
} else {
pantry.oldDate = newDate
print("old date = \(pantry.oldDate)")
print("true: show the date")
return true
}
}
}
实际代码:
struct ListView: View {
@EnvironmentObject var categories: Categories
@EnvironmentObject var userData: UserData
@Environment(\.managedObjectContext) var viewContext
var money: String = ""
var xchRate: Double = 0.0
var cat: Int = 0
var mny: String = ""
@FetchRequest(
entity: CurrTrans.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \CurrTrans.entryDT, ascending: true)]
) var currTrans: FetchedResults<CurrTrans>
var body: some View {
GeometryReader { g in
ScrollView {
LazyVStack (alignment: .leading) {
TitleView()
ForEach(currTrans, id: \.self) { item in
showRow(item: item, priorDate: priorDate(forItemIndex: item), g: g)
}
.onDelete(perform: deleteItem)
}
.font(.body)
}
}
}
private func priorDate(forItemIndex item: Int) -> Date? {
guard item > 0 else { return nil }
return currTrans[item - 1].entryDT
}
}
struct showRow: View {
@EnvironmentObject var userData: UserData
var item: CurrTrans
var priorDate: Date?
var g: GeometryProxy
var payType = ["Cash/Debit", "Credit"]
var body: some View {
// don't show the date if is the same as the previous entry
let gotDate = item.entryDT ?? Date()
let newDate = gotDate.getFormattedDate()
Text("\(newDate)")
.opacity(gotDate == priorDate ? 0 : 1)
.font(.title2)
.padding(.leading, 10)
displays entry parameters in HStack...
【问题讨论】:
-
不相关,但请注意
ContentView和showRow中的pantry对象是两个不同的实例。您应该只创建一次ObservableObject并将其传递到层次结构中。 -
感谢您指出我的班级 Pantry 有不止一个实例。看起来我的示例代码已经消失了!我是一名长期从事 C 和汇编工作的固件工程师,我们不必担心类和实例。我的实际代码确实通过层次结构向下传递,并且条目存储在 coredata 中。这是获取:@FetchRequest(实体:CurrTrans.entity(),sortDescriptors:[NSSortDescriptor(keypath:\CurrTrans.entryDT,升序:true)] var currTrans:FetchedResults