代码之家  ›  专栏  ›  技术社区  ›  charelf

SwiftUI嵌套ForEach导致随机行为

  •  0
  • charelf  · 技术社区  · 4 年前

    ForEach()

    我的问题是 ForEach 在第二次访问时表现得很奇怪 ForEach公司 .

    enter image description here

    在我附加的这个gif中,Round后面的第一个变量( ri 在下面的代码段中)当我向上或向下滚动时,有时会更改其值。但是,这个变量的值在第一个变量中总是相同的 ,从节名称可以看出,显示的轮始终是正确的轮。

    下面是带有嵌套 ForEach公司

            List {
                ForEach(Array(self.game.rounds.indices), id: \.self) { ri in
                    Section(header: Text("Round \(ri): \(self.game.rounds[ri])")) {
                        ForEach(Array(self.game.players.indices), id: \.self) { pi in
                            HStack {
                                Text("\(self.game.players[pi])")
                                Text("Round \(ri), Player \(pi)")
                            }
                        }
                    }
                }
            }
    

    下面是包含嵌套 ForEach公司

    https://github.com/charelF/carioca/blob/master/unote/GameView.swift

    我很确定我遇到的实际上是SwiftUI中的一个bug。但是我不确定,这种行为可能是预期的行为或某种异步加载单元的行为。


    编辑1:

            List {
                ForEach([10,11,12,13,14,15,16,17,18,19] /*Array(self.game.rounds.enumerated())*/, id: \.self) { ri in
                    Section(header: Text("Round \(ri-10): \(self.game.rounds[ri-10])")) {
                        ForEach(Array(self.game.players.indices), id: \.self) { pi in
                            HStack {
                                Text("ri \(ri), pi \(pi)")
                            }
                        }
                    }
                }
    

    id实际上是不一样的,但是行/单元格仍然是混乱的,如这个截图所示。。。

    此外,考虑到我需要索引,我正在努力找到一种迭代这两个数组的好方法,这样我就可以真正迭代数组本身了。我能想到的唯一解决办法是要么是像上面那样丑陋的东西,用 .enumerate() (我试过了,得到了和上面类似的错误),或者把数组转换成具有唯一键的字典。。。


    编辑2:

    Round Player Int 我以前用过的。这意味着我可以写我的名字 ForEach公司 具体如下:

            List {
                ForEach(self.game.rounds, id: \.id) { round in
                    Section(header: Text("\(round.number): \(round.desc)")) {
                        ForEach(self.game.players, id: \.id) { player in
                            Text("\(player.name), \(round.number)")
                        }
                    }
                }
            }
    

    Game.swift https://github.com/charelF/carioca/blob/master/unote/Game.swift

    不幸的是,这并没有解决问题。秩序仍然混乱。尽管我相信我已经理解了这个问题,但我不知道如何用其他方法来解决它。


    编辑3:

    Nested ForEach (and List) in Views give unexpected results )(将视图封闭在外部 但是,错误仍然存在


    编辑4:

    我终于让它工作,不幸的是,我的解决方案是一个更黑客和真的不是很干净。解决方案确实如答案所示,所有单元格都需要唯一标识符。

    List {
        ForEach(self.game.rounds) { round in
            Group {
                Section(header: Text("\(round.number): \(round.desc)")) {
                    ForEach(self.game.scoreBoard[round]!, id: \.self.id) { sbe in
                        Text("\(round.number) \(sbe.id)")
                        
                    }
                }
            }
        }
    }
    

    如下面的截图所示,第7轮下面的4个单元格与第8轮下面的4个单元格具有不同的标识符,如果我理解正确,这就解决了我的问题。

    不幸的是,在我的游戏逻辑中,这个解决方案需要一些丑陋的变通方法。

    0 回复  |  直到 4 年前
        1
  •  6
  •   Asperi    4 年前

    在所描述的场景中,应该为行中显示的项目选择一些独特的内容,比如(scratchy)

    ForEach(self.game.rounds) { round in  // make round identifiable
          // ...
            ForEach(self.game.players) { player in // make player identifiable
    

    rounds ID不应与重叠 player 身份证也是。