誰能幫我解決這個問題?請在您的 Xcode 中粘貼相同的代碼并運行它。請按照以下步驟操作:
- 選擇日期為 2022 年 6 月 1 日,時間 1 為 07:00,時間 2 為 15:00。將 load1 輸入為 7,將 load2 輸入為 8。單擊 Add load。它將顯示日期、時間 1 和時間 2 以及總金額。
- 同樣保持時間相同(07:00-15:00)并將日期更改為 6 月 3 日和 6 月 4 日,并且使用不同的 load1 和 load2 值,單擊 Add load。
- 現在單擊編輯按鈕并洗掉 6 月 4 日和 6 月 1 日的資料,然后使用 6 月 2 日輸入新資料。6 月 3 日的日期和總額自動更改為 6 月 2 日。所以我現在有兩個資料都是 6 月 2 日。Total 也有不同的值。為什么會這樣?知道我在哪里做錯了嗎?
struct Task : Identifiable {
var id = String()
var toDoItem = String()
var amount : Float = 0 //<-- Here
}
class TaskStore : ObservableObject {
@Published var tasks = [Task]()
}
struct Calculation: View {
@State var load1 = Float()
@State var load2 = Float()
@State var gp : Float = 0
@State var rate: Float = 0
@ObservedObject var taskStore = TaskStore()
@State private var birthDate = Date()
@State private var time1 = Date()
@State private var time2 = Date()
func addNewToDo() {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
let dayoftime = formatter.string(from: birthDate)
let formatter2 = DateFormatter()
formatter2.dateFormat = "HH:mm"
let timeof1 = formatter2.string(from: time1)
let timeof2 = formatter2.string(from: time2)
taskStore.tasks.append(Task(id: String(taskStore.tasks.count 1), toDoItem: "\(dayoftime) \(timeof1)-\(timeof2) total = \(rate.description) ", amount: rate))
//gp = rate
}
var body: some View {
NavigationView {
VStack {
HStack {
VStack(spacing: 1) {
Section(header: Text("Date") .foregroundColor(.black)
){
DatePicker(selection: $birthDate, displayedComponents: [.date]){Text(" Time")
}
}
VStack(spacing: 1) {
Section(header: Text("Time1") .foregroundColor(.black)){
DatePicker(selection: $time1, displayedComponents: [.hourAndMinute]){Text(" Time 1")
}
}
VStack(spacing: 1) {
Section(header: Text("Time2") .foregroundColor(.black)
){ DatePicker(selection: $time2, displayedComponents: [.hourAndMinute]){Text(" Time 1")
}
}
}
List {
Section(header:Text("load 2"))
{
TextField("Enter value of load 1", value: $load1, format: .number)
TextField("Enter value of load 1", value: $load2, format: .number)
}
HStack {
Button(String(format: "Add Load"), action: {
print(Rocky(mypay: rate))
gp = rate
})
Button(action: {
addNewToDo()
Rocky(mypay: rate)
},
label: {
Text(" ")
})
}
ForEach(self.taskStore.tasks) { task in
Text(task.toDoItem)
}
.onMove(perform : self.move)
.onDelete(perform : self.delete) //For each
}
.navigationBarTitle("SHIFTS")
.navigationBarItems(trailing: EditButton()) //List
Text("Total = $\(gp) ")
}.onAppear()
}
}
}
}
}
func Rocky(mypay: Float)
{
rate = load1 load2
print("Sus \(gp)")
}
func move(from source : IndexSet, to destination : Int)
{
taskStore.tasks.move(fromOffsets: source, toOffset: destination)
}
func delete(at offsets : IndexSet) {
if let index = offsets.first { //<-- Here
let task = taskStore.tasks[index]
gp -= task.amount
}
taskStore.tasks.remove(atOffsets: offsets)
}
}
uj5u.com熱心網友回復:
問題是ForEach需要您的物品是唯一可識別的。
您正在id為您的任務使用自動生成的,基本上計算為存盤中的當前任務計數:
taskStore.tasks.append(Task(id: String(taskStore.tasks.count 1), ......`
這就是正在發生的事情:
- 您添加前三個任務,它們將獲得 和
"1"的"2"ID"3"。 - 您洗掉具有 ID
"1"和的任務"3"。唯一留在陣列中的任務是 ID 為 的任務"2"。 - 您正在向串列中添加另一個任務。創建任務時,陣列中的任務數為 1,因此新任務的 ID 為
"2"。因此,現在您在陣列中有兩個具有相同 ID 的不同任務。 - 當 SwiftUI 呈現您的視圖時,該
ForEach方法通過 ID 區分您的任務。它看到它應該呈現串列的兩行,并且它們的 ID 都是"2". 因此,它會找到 ID 等于的第一個專案并將其"2"渲染兩次,因為它假定陣列中的所有專案都具有唯一的 ID(實際上應該具有)。
要解決此問題,請使用 aUUID作為任務的識別符號。您還可以創建一個不將 ID 作為引數的初始化程式,因為該任務將為自己創建一個唯一識別符號:
struct Task: Identifiable {
var id: UUID
var toDoItem: String
var amount: Float
init(toDoItem: String, amount: Float) {
self.id = UUID()
self.toDoItem = toDoItem
self.amount = amount
}
}
當創建一個新任務時,使用這個新的初始化器而不給專案分配一個明確的識別符號:
taskStore.tasks.append(
Task(
toDoItem: "\(dayoftime) \(timeof1)-\(timeof2) total = \(rate.description) ",
amount: rate
)
)
就是這樣,現在所有任務都將具有唯一識別符號并正確呈現。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/489135.html
標籤:迅速 迅捷 swiftui 列表 swiftui-foreach
