预期行为:
- 用户每天至少输入一个条目。
- 用户看到"请输入"按钮
- 除非他们已经有了,否则按钮会显示"保存",如果他们点击它,它会转到历史视图。(按钮切换到导航视觉上表明发生了一些事情)。
我的想法是在日期上应用一个 predicate ,以便按一天的开始进行过滤,并使用if语句交换所看到的内容。
当我应用下面的代码时,它在模拟器和应用程序中运行良好,但 * 几天后 * predicate 停止工作。我在一天开始时打开应用程序,它显示"已保存"。大约2 - 3个晚上后,我不知道是什么坏了。不确定这是否是实现结果的最佳解决方案。
还有,如果我杀死应用程序并重新加载,一切又都好了。
我尝试了一个版本的this答案,但我仍然是一个新的编码,可能没有做正确的事情,因为它根本不工作(显示核心数据中的所有结果)。
import SwiftUI
import CoreData
struct HomeScreenView: View {
@EnvironmentObject var backgroundSet: Background
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Entry.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: true)], predicate: nil, animation: .default)
private var entries: FetchedResults<Entry>
init(){
var calendar = Calendar.current
calendar.timeZone = NSTimeZone.local
let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
let predicate = NSPredicate(format : "date <= %@ AND date >= %@", dateTo! as CVarArg, dateFrom as CVarArg)
self._entries = FetchRequest(
entity: Entry.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: false)],
predicate: predicate)
}
@State var presentSheet = false
@State private var today : Date = Date()
var body: some View {
NavigationStack {
ZStack {
if entries.count == 0 {
Button("Please make an entry?") {
presentSheet = true
//refresh.toggle()
}
.frame(minWidth: 250, minHeight: 50, alignment: .center).padding()
.cornerRadius(40)
.padding()
} else {
NavigationLink(destination: HistoryView()) {
VStack {
Text("Saved for today.")
Text("Click here to view history.")
}
}
.frame(minWidth: 250, minHeight: 50, alignment: .center).padding()
.cornerRadius(40)
.padding()
}
}
.sheet(isPresented: $presentSheet) {
AddEntryView()
.presentationDetents([.medium])
}
下面是持久性的副本:
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
for _ in 0..<10 {
let newEntry = Entry(context: viewContext)
newEntry.timestamp = Date()
}
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentContainer
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "Express_Gratitude")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
以下是@main中的内容
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
从上面的链接,我尝试了一个版本,它没有工作。我可能是实施这完全错误的...开放的教育和建议,以实现的结果。
import SwiftUI
import CoreData
struct HomeScreenView: View {
@EnvironmentObject var backgroundSet: Background
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Entry.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: true)], predicate: nil, animation: .default)
private var entries: FetchedResults<Entry>
init(){
// Get the current calendar with local time zone
var calendar = Calendar.current
calendar.timeZone = NSTimeZone.local
// Get today's beginning & end
let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
// Note: Times are printed in UTC. Depending on where you live it won't print 00:00:00 but it will work with UTC times which can be converted to local time
// Set predicate as date being today's date
let fromPredicate = NSPredicate(format: "%@ >= %K", dateFrom as NSDate, #keyPath(Entry.date))
let toPredicate = NSPredicate(format: "%K < %@", #keyPath(Entry.date), dateTo! as NSDate)
let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])
self._entries = FetchRequest(
entity: Entry.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: false)],
predicate: datePredicate)
}
@State var presentSheet = false
@State private var today : Date = Date()
1条答案
按热度按时间svdrlsy41#
我认为你需要在日期变化时更新 predicate ,例如。
请注意,您还需要使用此日历,因此,如果用户在应用运行时在“设置”中更改其日历,则会重新创建计时器。