#swift #swiftui #swift-dictionary
#swift #swiftui #swift-словарь
Вопрос:
Как моделировать заметки, чтобы я мог искать их после по датам? как на картинке.
Во-первых, я думал о словаре с ключом типа Date
; но у меня это не сработало. Итак, я попробовал следующий String
формат:
«04-28-2020» — календарь США
«28-04-2020» — Другой календарь
Одна из проблем — если телефон меняет стиль даты (зависит от региона), ключи остаются в словаре, но к ним больше не обращаются…
Моя интуиция, что это должен быть словарь, но каков устойчивый способ создания такой модели? Может ли это быть массив заметок [Note]
без ключей?
struct Note: Codable, Identifiable {
let id = UUID()
var date: Date
var title: String
var description: String
var dateString: String {
let df = DateFormatter()
df.dateStyle = .short
df.timeStyle = .medium
return df.string(from: date)
}
// method returns "key" to be used in dictionary
static func dateKey(for date: Date) -> String {
let df = DateFormatter()
df.dateStyle = .short
return df.string(from: date)
}
}
class NotesOrganizer: ObservableObject {
// @Published var notes = [Note]() - tried initially
@Published var notesDictionary = [String : [Note]]()
}
struct ContentView: View {
@State private var title = ""
@State private var description = ""
@ObservedObject var notesOrganizer = NotesOrganizer()
var body: some View {
NavigationView {
VStack {
Button("Save note") {
let key = Note.dateKey(for: Date())
notesOrganizer.notesDictionary[key]?.append(Note(date: Date(), title: title, description: description))
?? (notesOrganizer.notesDictionary[key] = [Note(date: Date(), title: title, description: description)])
print("Date Key: (Note.dateKey(for: Date()))")
}
NavigationLink(destination: DetailView(notesOrganizer: notesOrganizer))
{
Text("Log history ->")
.foregroundColor(.purple)
.underline()
}
}
.navigationBarHidden(true)
}
}
init() {
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
UINavigationBar.appearance().shadowImage = UIImage()
}
}
Просмотр деталей()
extension Date {
var tomorrow: Date? {
return Calendar.current.date(byAdding: .day, value: 1, to: self)
}
var yesterday: Date? {
return Calendar.current.date(byAdding: .day, value: -1, to: self)
}
}
struct DetailView: View {
@ObservedObject var notesOrganizer: NotesOrganizer
@State private var dayLabel: String = Note.dateKey(for: Date())
@State private var chosenDate = Date()
var body: some View {
VStack {
HStack {
Button(action: {
chosenDate = chosenDate.yesterday!
dayLabel = Note.dateKey(for: chosenDate)
}, label: {
Image(systemName: "chevron.left")
})
Text(dayLabel)
Spacer()
Button(action: {
chosenDate = chosenDate.tomorrow!
dayLabel = Note.dateKey(for: chosenDate)
}, label: {
Image(systemName: "chevron.right")
})
}
.padding([.horizontal,.bottom])
List{
ForEach(notesOrganizer.notesDictionary[day] ?? []) { note in
HStack {
VStack(alignment:.leading) {
Text(note.title)
Text(note.description)
}.multilineTextAlignment(.leading)
Spacer()
Text(note.dateString)
}
}.onDelete(perform: removeItems)
}
.navigationBarTitle("", displayMode: .inline)
Spacer()
}
Комментарии:
1. Вы могли бы использовать основные данные. Создайте модель заметок, дайте ей атрибуты, связанные с датой: конечно, объект даты, но также, возможно, строку, представляющую «раздел месяца» или «раздел дня», который вам нужен, например, note.section (т. Е. «2020/12/31»), или даже простые целые числа. Нравится: примечание. год (2020), примечание.месяц (12), примечание.день (31), примечание.час, примечание.минута и т.д. Затем вы должны выполнить поиск с помощью NSPredicate Core Data по этим атрибутам.
2. @EricAya будет ли это также работать для переключения дат, как на картинке? и словарь не нужен? Как и каждый раз, когда пользователь переключает метку даты, он будет выполнять поиск по данным из CoreData?
3. Если вы еще не знакомы с Core Data, я предлагаю использовать простую структуру заметок с атрибутами даты, как я объяснил, и привести ее в соответствие с Codable и сохранить массив заметок в формате JSON. Это легко сделать, и затем вы сможете изучить, как выполнять поиск по ним,
.filter
например, с помощью. Если через некоторое время вы увидите, что вам нравится эта система, перейдите к Core Data, которая будет «профессиональной» версией. // Всегда сохраняйте все даты как UTC (и / или используйте формат ISO, например «2020/12/31» для хранения строк дат). Затем отформатируйте дату, используя языковой стандарт / календарь пользователя, прежде чем отображать ее.