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

时间:2020-08-09 20:26:42

标签: swift swiftui swiftui-list swiftui-foreach

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

代码如下:

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 个答案:

答案 0 :(得分: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