Swift array.append() 未按预期工作

Swift array.append() not working as expected

我是 Swift 的新手,似乎无法使用此附加方法,如有任何帮助,我们将不胜感激!

这是我的模型和视图:

import SwiftUI

struct ContentView: View {
    @Binding var gameInformation: GameInformation
    
    var body: some View {
        VStack(alignment: .center) {
            Button("Append") {
                let index = gameInformation.sets.firstIndex(of: gameInformation.sets.last!)
                gameInformation.sets[index!].legs.append(Leg())
                print(gameInformation.sets[index!].legs)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(gameInformation: .constant(GameInformation()))
    }
}

struct GameInformation: Identifiable, Codable {
    var id = UUID()
    
    var sets: [Set] = [Set()]
    
    enum CodingKeys: String, CodingKey {
         case id, sets
     }
}

struct Set: Codable, Equatable, Identifiable {
    static func == (lhs: Set, rhs: Set) -> Bool {
        return lhs.id == rhs.id
    }
    
    var id: String = UUID().uuidString
    var legs: [Leg] = []
}

struct Leg: Codable, Identifiable {
    var id: String = UUID().uuidString

    var playerOneScores: [Int] = []
    var playerTwoScores: [Int] = []
}

如您所见,我有一个父 GameInformation 模型,它有 sets,它是 Set 的数组,然后 Setlegs,它是一个Leg的数组,内容视图中的按钮只是添加了一个新的Leg,但是当打印gameInformation.sets[index!].legs的值时,只有一个条目是初始化值。

再次感谢您的帮助。

您在 Set 上编写了 Equatable 的实现(我已将其重命名为 MySet -- 请参阅注释了解原因),这妨碍了您的工作。现在,您的实现告诉 SwiftUI 如果 id 属性 相同,则元素相等。因此,如果 legs 发生变化,SwiftUI 不会更新,因为它认为元素仍然相同。

相反,您可以删除自定义 Equatable 一致性并使 Leg Equatable 也一样。

struct GameInformation: Identifiable, Codable {
    var id = UUID()
    
    var sets: [MySet] = [MySet()] //<-- Renamed
    
    enum CodingKeys: String, CodingKey {
         case id, sets
     }
}

struct MySet: Codable, Equatable, Identifiable { //<-- Satisfies Equatable because all of its properties are Equatable
    var id: String = UUID().uuidString
    var legs: [Leg] = []
}

struct Leg: Codable, Identifiable, Equatable { //<-- Marked as Equatable as well
    var id: String = UUID().uuidString

    var playerOneScores: [Int] = []
    var playerTwoScores: [Int] = []
}