下面是我的任务管理应用程序中的一个视图,我试图使我的选择器在被选中时显示一定的颜色。我的问题是如何保存用于核心数据中的优先级和颜色选择器的int ?我不知道如何将int值转换为int32,它不能作为int32对象开始,因为那样它就不能被用作每个选择器的背景颜色的选择器。请帮助!
struct NewTask: View {
@Environment(.dismiss) var dismiss
// MARK: Task Values
@State var taskTitle: String = ""
@State var taskDescription: String = ""
@State var taskDate: Date = Date()
var colors = ["Teal","Yellow","Pink"]
@State var selectedColor: Int = 0
var colorsColors = ["logoTeal","logoYellow","logoPink"]
var selectedColorInt: String {
get {
return ("(selectedColor)")
}
}
var priorities = ["Urgent","Slightly Urgent","Not Urgent"]
@State var selectedPriority: Int = 0
var priorityColors = ["priorityRed","priorityYellow","priorityGreen"]
// MARK: Core Data Context
@Environment(.managedObjectContext) var context
@EnvironmentObject var taskModel: TaskViewModel
var body: some View {
NavigationView{
List{
Section {
TextField("Go to work", text: $taskTitle)
Picker("Priority", selection: $selectedPriority) {
ForEach(0..<priorities.count){
Text(priorities[$0])
}
.padding(5)
.foregroundColor(.white)
.background(priorityColors[selectedPriority])
.cornerRadius(5)
}
Picker("Theme", selection: $selectedColor) {
ForEach(0..<colors.count){
Text(colors[$0])
}
.padding(5)
.foregroundColor(.black)
.background(colorColors[selectedColor])
.cornerRadius(5)
}
} header: {
Text("Task Information")
}
Section {
TextEditor(text: $taskDescription)
} header: {
Text("Task Description")
}
// Disabling Date for Edit Mode
if taskModel.editTask == nil{
Section {
DatePicker("", selection: $taskDate)
.datePickerStyle(.graphical)
.labelsHidden()
} header: {
Text("Task Date")
}
}
}
.listStyle(.insetGrouped)
.navigationTitle("Add New Task")
.navigationBarTitleDisplayMode(.inline)
// MARK: Disbaling Dismiss on Swipe
.interactiveDismissDisabled()
// MARK: Action Buttons
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Save"){
if let task = taskModel.editTask{
task.taskTitle = taskTitle
task.taskDescription = taskDescription
}
else{
let task = Task(context: context)
task.taskTitle = taskTitle
task.taskDescription = taskDescription
task.taskDate = taskDate
/*task.selectedColor = selectedColor*/
/*task.selectedPriority = selectedPriority*/
}
// Saving
try? context.save()
// Dismissing View
dismiss()
}
.disabled(taskTitle == "" || taskDescription == "")
}
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel"){
dismiss()
}
}
}
// Loading Task data if from Edit
.onAppear {
if let task = taskModel.editTask{
taskTitle = task.taskTitle ?? ""
taskDescription = task.taskDescription ?? ""
}
}
}
}
}
我将采用以下方法:
首先,由于优先级只能是三个值中的一个,因此将其表示为具有Int32原始值的enum,并将文本描述和颜色作为enum的属性:
enum Priority: Int32, CaseIterable {
case urgent = 0
case slightlyUrgent = 1
case notUrgent = 2
var description: String {
switch self {
case .urgent: return "Urgent"
case .slightlyUrgent: return "Slightly Urgent"
case .notUrgent: return "Not Urgent"
}
}
var colorName: String {
switch self {
case .urgent: return "PriorityRed"
case .slightlyUrgent: return "PriorityYellow"
case .notUrgent: return "PriorityGreen"
}
}
var color: Color { Color(colorName) }
}
在形式中,这使您的代码更干净,并允许您在初始化状态变量时使用0
上的语义值:
@State private var selectedPriority: Priority = .urgent
Picker("Priority", selection: $selectedPriority) {
ForEach(Priority.allCases, id: .self) { priority in
Text(priority.description)
.padding(5)
.foregroundColor(.black)
.background(priority.color)
.cornerRadius(5)
}
}
然后,向CoreData模型添加扩展,为其提供Priority
属性,添加getter和setter,以便它使用存储的列:
extension Task {
var priorityEnum: Priority {
get { Priority(rawValue: priority) ?? .urgent }
set { priority = newValue.rawValue }
}
}
然后,当涉及到将表单详细信息保存到Core Data管理对象时,您可以将task.priorityEnum
设置为选择器的值,并且自定义属性将确保存储正确的Int32
值。
同样,当从任务中加载编辑表单的状态变量时,引用task.priorityEnum
将获得一个用存储在数据库中的整数初始化的Priority
值。