gpt4 book ai didi

SwiftUI Nested ForEach 导致意外排序

转载 作者:行者123 更新时间:2023-12-03 09:24:14 25 4
gpt4 key购买 nike

我正在使用两个 ForEach()以嵌套方式,一个显示部分,另一个显示 ListView 的单个单元格。
我的问题是第一个 ForEach 中的迭代器变量在第二个 ForEach 中访问它时的行为非常奇怪.
enter image description here
在我附上的这个 gif 中,Round 后面的第一个变量(下面代码片段中的 ri)有时会在我向上或向下滚动时更改其值。然而,这个变量的值在第一个 ForEach 中总是相同的。 ,正如我们通过部分名称所看到的,显示的回合总是正确的。
这是带有嵌套 ForEach 的代码声明。但是,正如此处介绍的那样,您可能无法重现该错误。虽然可能迷信,但似乎我的 View 越复杂,错误出现的可能性就越大。

        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 的完整 View 这给我带来了问题:
https://github.com/charelF/carioca/blob/master/unote/GameView.swift
我相当确定我遇到的实际上是 SwiftUI 中的一个错误。但是我不确定,这种行为可能是预期的行为或某种单元格的异步加载。

编辑1:
要么我做错了什么,要么@Asperi 的答案似乎并没有真正解决问题。这是一个快速而肮脏的解决方法,我试图避免 ID 相同
        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 )(用一组将 View 封闭在外部 ForEach 内),但是错误仍然存​​在

编辑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 个单元格具有不同的标识符,如果我理解正确,这解决了我的问题。

不幸的是,该解决方案在我的游戏逻辑中需要一些非常丑陋的解决方法。 https://github.com/charelF/carioca/blob/master/unote/Game.swift

最佳答案

由于行的非唯一标识符而失败。是用的索引,但是在不同的节重复,所以List行重用缓存引擎混淆了。
在所描述的场景中,应该为按行显示的项目选择一些独特的东西,比如 (scratchy)

ForEach(self.game.rounds) { round in  // make round identifiable
// ...
ForEach(self.game.players) { player in // make player identifiable
rounds id 不应与 player 重叠id 也是如此。

关于SwiftUI Nested ForEach 导致意外排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62930684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com