I am a noob and I learning Swift and SwiftUI. I want to create an application for organize the notes. I have 2 problems.
//
// NewNoteView.swift
// List&Notes
//
// Created by Yoan on 18/04/2021.
//
import SwiftUI
struct NewNoteView: View {
let coreDM: CoreDataManger
@State var category: [Category] = [Category]()
@State private var categorySelected = Category()
@State private var categoryField = String()
@State private var noteField: String = "Your note here"
@State private var noteTitleField = String()
@State private var showButton = false
private func emptyField() {
categoryField = ""
noteField = ""
noteTitleField = ""
}
var body: some View {
VStack{
Form {
Picker("Select your category", selection: $categorySelected) {
ForEach(category, id: \.self) { categorize in
Text(categorize.title ?? "no value")
}
}
TextField("titleNote", text: $noteTitleField)
.font(.title2)
.background(Color.white)
.cornerRadius(5)
.shadow(radius: 5)
TextEditor(text: $noteField)
.padding(.bottom)
.font(.body)
.background(Color.white)
.shadow(radius: 5)
.cornerRadius(8)
}
Button(action: {
guard !noteTitleField.isEmpty && !noteField.isEmpty && categorySelected != nil else {
print("Error")
return
}
coreDM.saveNote(noteData: noteField, noteTitle: noteTitleField,
noteDate: Date(), noteCategory: categorySelected)
emptyField()
}, label: {
Text("Save")
}
)
.frame(maxWidth: .infinity, maxHeight: 40.0 )
.background(Color.yellow)
.shadow(radius: 10)
.cornerRadius(10)
}
.navigationTitle("Create new note")
.onAppear(perform: {
category = coreDM.getAllCategory()
})
}
}
struct NewNoteView_Previews: PreviewProvider {
static var previews: some View {
NavigationView{
NewNoteView(coreDM: CoreDataManger())
}
}
}
//
// ListView.swift
// List&Notes
//
// Created by Yoan on 18/04/2021.
//
import SwiftUI
struct ListView: View {
let coreDM: CoreDataManger
@State var notes: [Note] = [Note]()
@State var needsRefresh: Bool = false
@State var category: [Category] = [Category]()
private func updateListNote() {
notes = coreDM.getAllNotes()
category = coreDM.getAllCategory()
}
var body: some View {
List {
ForEach(notes, id: \.self) { notes in
NavigationLink(
destination: NoteDetailView(coreDM: coreDM, note: notes, needsRefresh: $needsRefresh),
label: {
HStack{
VStack{
Text(notes.title ?? "no value")
.font(.title2)
.multilineTextAlignment(.leading)
.lineLimit(1)
Text(notes.dataNote ?? "No description")
.font(.subheadline)
.foregroundColor(.gray)
.multilineTextAlignment(.leading)
.lineLimit(2)
}
Spacer()
VStack{
Text(notes.date!, style: .date)
Text(notes.date!, style: .time)
}
}
})
}
.onDelete(perform: { indexSet in
indexSet.forEach { index in
let note = notes[index]
coreDM.deleteNote(note: note)
updateListNote()
}
})
}
.listStyle(PlainListStyle())
.accentColor(needsRefresh ? .red: .blue)
.navigationTitle("Your notes")
.onAppear(perform: {
updateListNote()
})
}
}
struct ListView_Previews: PreviewProvider {
static var previews: some View {
ListView(coreDM: CoreDataManger())
}
}
You can find my project in my GitHub if you need. https://github.com/yoan8306/List-Notes.git
Sorry I'm French and my English is not very well. I hope it's my problem it's clear.
I fix my 1 query. Like say udbhateja
make categorySelected
as optional
@State private var categorySelected: Category? = nil
For fix selection in pickerView
we need add
.tag((categorize as Category?))
the code is
import SwiftUI
struct NewNoteView: View {
let coreDM: CoreDataManger
@State var category: [Category] = [Category]()
@State private var categorySelected : Category? = nil
@State private var categoryField = String()
@State private var noteField: String = "Your note here"
@State private var noteTitleField = String()
@State private var showButton = false
@State private var presentAlert = false
@State private var saveSuccess = false
@State private var selection = Category()
private func emptyField() {
categoryField = ""
noteField = ""
noteTitleField = ""
}
private func checkNoteIsOk() -> Bool{
if !noteTitleField.isEmpty && !noteField.isEmpty && categorySelected != nil {
return true
} else {
presentAlert = true
return false
}
}
var body: some View {
VStack{
Form {
Picker("Select your category", selection: $categorySelected ) {
ForEach(category, id: \.self) { categorize in
Text(categorize.title ?? "no value").tag((categorize as Category?))
}
}
TextField("titleNote", text: $noteTitleField)
.font(.title2)
.background(Color.white)
.cornerRadius(5)
.shadow(radius: 5)
TextEditor(text: $noteField)
.font(.body)
.background(Color.white)
.shadow(radius: 5)
.cornerRadius(8)
.padding(.bottom)
}
if let category = categorySelected {
Button(action: {
guard checkNoteIsOk() else {
return
}
coreDM.saveNote(noteData: noteField, noteTitle: noteTitleField,
noteDate: Date(), noteCategory: categorySelected!)
emptyField()
saveSuccess = true
},
label: {
Text("Save")
}
)
.frame(maxWidth: .infinity, maxHeight: 40.0 )
.background(Color.yellow)
.shadow(radius: 10)
.cornerRadius(10)
}
}
.navigationTitle("Create new note")
.onAppear(perform: {category = coreDM.getAllCategory()})
.alert(isPresented: $presentAlert) {
Alert(title: Text("Error !"), message: Text("Not saved"),
dismissButton: .default(Text("OK"))) }
.alert(isPresented: $saveSuccess) {
Alert(title: Text("Success !"), message: Text("Insert with success !"),
dismissButton: .default(Text("OK"))) }
}
}
struct NewNoteView_Previews: PreviewProvider {
static var previews: some View {
NavigationView{
NewNoteView(coreDM: CoreDataManger())
}
}
}
But I have new problem. I think it's simple. I would like make 2 alerts messages. The first it's when save is success and the second is when they are problem like one field is empty or category is empty.
private func checkNoteIsOk() -> Bool{
if !noteTitleField.isEmpty && !noteField.isEmpty && categorySelected != nil {
return true
} else {
presentAlert = true
return false
}
}
.
Button(action: {
guard checkNoteIsOk() else {
// present alert here
return
}
coreDM.saveNote(noteData: noteField, noteTitle: noteTitleField,
noteDate: Date(), noteCategory: categorySelected!)
emptyField()
( ..present saveSuccess alert here..)
saveSuccess = true
},
label: {
Text("Save")
}
) //end button
code ....
} //end Vstak
.navigationTitle("Create new note")
.alert(isPresented: $presentAlert) {
Alert(title: Text("Error !"), message: Text("Not saved"),
dismissButton: .default(Text("OK"))) }
.alert(isPresented: $saveSuccess) {
Alert(title: Text("Success !"), message: Text("Insert with success !"),
dismissButton: .default(Text("OK"))) }
I think it's because they are two alerts messages. And only the last message alert can display. Thank you for your answer and your help.