问题描述
我是菜鸟,正在学习 Swift 和 SwiftUI。 我想创建一个应用程序来组织笔记。 我有两个问题。
- 我想控制用户在按下按钮之前何时在选择器视图中选择了类别。如果未选择类别,则隐藏按钮保存。
- 在 ListView 中按类别对列表中的笔记进行排序。
//
// 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())
}
}
如果需要,您可以在我的 GitHub 中找到我的项目。 https://github.com/yoan8306/List-Notes.git
对不起,我是法国人,我的英语不太好。 我希望这是我的问题,很清楚。
解决方法
对于您的第一个查询,请在代码中更改以下内容:
将 categorySelected
设为可选
@State private var categorySelected: Category? = nil
在VStack中添加if条件来显示按钮
if let category = categorySelected {
Button(action: {
guard !noteTitleField.isEmpty && !noteField.isEmpty 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)
}
对于您的第二个问题,请澄清 - 您是否需要根据类别或其他内容在部分中显示数据。
,我修复了 1 个查询。就像说 udbhateja
将 categorySelected
设为可选
@State private var categorySelected: Category? = nil
用于在 pickerView 中修复选择
我们需要添加
.tag((分类为类别?))
代码是
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,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())
}
}
}
但是我有新的问题。我认为这很简单。 我想发出 2 条警报消息。 第一个是当保存成功时,第二个是当它们出现问题时,例如一个字段为空或类别为空。
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,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 !"),dismissButton: .default(Text("OK"))) }
.alert(isPresented: $saveSuccess) {
Alert(title: Text("Success !"),dismissButton: .default(Text("OK"))) }
我认为这是因为它们是两条警报消息。并且只能显示最后一条消息警报。 感谢您的回答和帮助。