CircleImage 在选择器中选择一个选项并添加到列表后不断改变颜色

Posted

技术标签:

【中文标题】CircleImage 在选择器中选择一个选项并添加到列表后不断改变颜色【英文标题】:CircleImage keeps changing colour after selecting an option in picker and adding to list 【发布时间】:2020-08-09 20:26:42 【问题描述】:

我遇到了一个奇怪的问题,当添加具有不同颜色的新项目时,列表中项目的颜色会发生变化,本质上它不会保留其颜色值,而是采用新的颜色值。 我要做的是显示与用户选择的优先级相对应的颜色。

代码如下:

struct PriorityGreen: View 
    var body: some View 
        Circle()
            .frame(width: 20, height: 20)
            .foregroundColor(Color.green)
    


struct PriorityYellow: View 
    var body: some View 
        Circle()
            .frame(width: 20, height: 20)
            .foregroundColor(Color.yellow)
    


struct PriorityOrange: View 
    var body: some View 
        Circle()
            .frame(width: 20, height: 20)
            .foregroundColor(Color.orange)
    


struct PriorityRed: View 
    var body: some View 
        Circle()
            .frame(width: 20, height: 20)
            .foregroundColor(Color.red)
    

查看代码

import SwiftUI

struct AppView: View 
    @ObservedObject var data = Model()

    @State var showViewTwo = false

    var body: some View 
        NavigationView 
            VStack 
                List 
                    ForEach(data.arrayOfTask, id: \.self)  row in
                        HStack 
                            if self.data.priority == 0 
                                PriorityGreen()
                             else if self.data.priority == 1 
                                PriorityYellow()
                             else if self.data.priority == 2 
                                PriorityOrange()
                             else if self.data.priority == 3 
                                PriorityRed()
                            
                            Text("\(row)")
                        
                    
                        .onDelete(perform: removeItems).animation(.default)
                
                    .listStyle(GroupedListStyle())
                    .environment(\.horizontalSizeClass, .regular)
            
                .navigationBarTitle("Tasks")
                .navigationBarItems(leading:
                        EditButton().animation(.default),
                    trailing: Button(action: 
                        self.showViewTwo.toggle()
                    ) 
                        Text("New task")
                    .sheet(isPresented: $showViewTwo) 
                        ViewTwo(data: self.data, showViewTwo: self.$showViewTwo)
                    )
        
    



    func removeItems(at offset: IndexSet) 
        data.arrayOfTask.remove(atOffsets: offset)
    


struct AppView_Previews: PreviewProvider 
    static var previews: some View 
        AppView()
    


struct ViewTwo: View 
    @State var data: Model
    @State var newName = ""
    @State var newCatergory = ""
    @State var newPriorityLevel = ""

    @State var defaultPriorityLevel = 1
    @State var priorityTypes = ["low", "medium", "high", "critical"]


    @Binding var showViewTwo: Bool
    var body: some View 
        NavigationView 
            Form 
                Section(header: Text("Add task name")) 

                    TextField("Name", text: $newName)
                    /*
                    This section will be implementated later on
                    TextField("Catergory", text: $newCatergory)
                    */
                
                Section(header: Text("Select task priority")) 
                    Picker("Priority Levels", selection: $defaultPriorityLevel) 
                        ForEach(0..<priorityTypes.count) 
                            Text(self.priorityTypes[$0])
                        
                    
                        .pickerStyle(SegmentedPickerStyle())
                
            
                .navigationBarTitle("New task details")
                .navigationBarItems(trailing:
                        Button("Save") 
                            self.showViewTwo.toggle()
                            self.data.taskName = self.newName
                            self.data.arrayOfTask.append(self.newName)
                            self.data.priority = self.defaultPriorityLevel
                    )
        
    


struct PriorityCirleView: View 
    var body: some View 
        Circle()
            .frame(width: 20, height: 20)
            .foregroundColor(Color.green)
    

import SwiftUI

enum Catergory 
    case work
    case home
    case family
    case health
    case bills


enum Priority 
    case low
    case medium
    case high
    case critical




class Model: ObservableObject 
    @Published var taskName = ""
    @Published var taskCategory = ""
    @Published var priority = 0

    @Published var arrayOfTask = [String]()


这个 gif 更清楚地展示了这个问题

(Gif)[https://imgur.com/a/ffzpSft]

【问题讨论】:

在帖子中添加了模型 【参考方案1】:

您的模型中只有一个优先级,而不是每个任务的优先级。

将您的模型更改为:

class Model: ObservableObject 
    struct Task 
        var taskName = ""
        var taskCategory = ""
        var priority = 0
    

    @Published var arrayOfTask = [Task]()

并更新您的代码以使用新模型:

struct AppView: View 
    @ObservedObject var data = Model()

    @State var showViewTwo = false

    var body: some View 
        NavigationView 
            VStack 
                List 
                    ForEach(data.arrayOfTask, id: \.taskName)  task in
                        HStack 
                            if task.priority == 0 
                                PriorityGreen()
                             else if task.priority == 1 
                                PriorityYellow()
                             else if task.priority == 2 
                                PriorityOrange()
                             else if task.priority == 3 
                                PriorityRed()
                            
                            Text("\(task.taskName)")
                        
                    
                        .onDelete(perform: removeItems).animation(.default)
                
                    .listStyle(GroupedListStyle())
                    .environment(\.horizontalSizeClass, .regular)
            
                .navigationBarTitle("Tasks")
                .navigationBarItems(leading:
                        EditButton().animation(.default),
                    trailing: Button(action: 
                        self.showViewTwo.toggle()
                    ) 
                        Text("New task")
                    .sheet(isPresented: $showViewTwo) 
                        ViewTwo(data: self.data, showViewTwo: self.$showViewTwo)
                    )
        
    



    func removeItems(at offset: IndexSet) 
        data.arrayOfTask.remove(atOffsets: offset)
    


struct ViewTwo: View 
    @State var data: Model
    @State var newName = ""
    @State var newCatergory = ""
    @State var newPriorityLevel = ""

    @State var defaultPriorityLevel = 1
    @State var priorityTypes = ["low", "medium", "high", "critical"]


    @Binding var showViewTwo: Bool
    var body: some View 
        NavigationView 
            Form 
                Section(header: Text("Add task name")) 

                    TextField("Name", text: $newName)
                    /*
                    This section will be implementated later on
                    TextField("Catergory", text: $newCatergory)
                    */
                
                Section(header: Text("Select task priority")) 
                    Picker("Priority Levels", selection: $defaultPriorityLevel) 
                        ForEach(0..<priorityTypes.count) 
                            Text(self.priorityTypes[$0])
                        
                    
                        .pickerStyle(SegmentedPickerStyle())
                
            
                .navigationBarTitle("New task details")
                .navigationBarItems(trailing:
                        Button("Save") 
                            var task = Model.Task()
                            self.showViewTwo.toggle()
                            task.taskName = self.newName
                            task.priority = self.defaultPriorityLevel
                            self.data.arrayOfTask.append(task)
                    )
        
    


使用taskName 作为id 不是一个好主意。更新您的 Task 结构以包含唯一值:

class Model: ObservableObject 
    struct Task: Identifiable 
        static var uniqueID = 0
        var taskName = ""
        var taskCategory = ""
        var priority = 0
        var id = 0
        
        init() 
            Task.uniqueID += 1
            self.id = Task.uniqueID
        
    

    @Published var arrayOfTask = [Task]()

然后改变:

ForEach(data.arrayOfTask, id: \.taskName)  task in

ForEach(data.arrayOfTask)  task in

【讨论】:

感谢您的回复,代码现在按预期工作,我会在早上第一件事尝试更好地理解它。再次感谢您。 检查我的更新。该代码使用taskName 作为id,这意味着具有相同名称的2 个任务将显示相同的优先级。我创建了Task Identifiable 并为其添加了一个独特的id 值。

以上是关于CircleImage 在选择器中选择一个选项并添加到列表后不断改变颜色的主要内容,如果未能解决你的问题,请参考以下文章

日期选择器中的 maxDate 选项

如何在选择器中快速获取所选项目的标题和项目的价值?

如何在选择器中添加/删除选项? [复制]

JQuery:如何抓取选择器中选择的内容

如何在引导选择选择器中为选项(下拉菜单)设置固定宽度

Element学习笔记:如何在选择器中默认绑定对象