为什么即使列表已正确更新,上下文菜单仍显示旧状态?
Why does Context Menu display the old state even though the List has correctly been updated?
我遇到了一个问题,即显示的 Context Menu
显示了错误的数据,尽管下面的 List
显示了正确的数据。问题是,一旦触发第一项的上下文菜单上的操作,您将看到 List
如何重新呈现并显示正确的数据,但是如果您再次为第一项触发上下文菜单,它不会显示正确的状态。如果你打开第二个项目的上下文菜单,它会显示正确的状态,但如果你现在 select “Two”,并打开相同的上下文菜单,State
将是错误的(它'当它应该显示 1 和 2 时,我将只显示 1 selected,就像 List
显示它一样)。
感觉差了一个(比如显示以前的状态而不是最新的状态)我不确定这只是一个错误还是我用错了。
这是重现问题的代码片段:
@main
struct ContextMenuBugApp: App {
let availableItems = ["One", "Two", "Three", "Four", "Five"]
@State var selectedItems: [String] = []
var body: some Scene {
WindowGroup {
List {
ForEach(availableItems, id: \.self) { item in
HStack {
let isAlreadySelected = selectedItems.contains(item)
Text("Row \(item), selected: \(isAlreadySelected ? "true" : "false")")
}.contextMenu {
ForEach(availableItems, id: \.self) { item in
let isAlreadySelected = selectedItems.contains(item)
Button {
isAlreadySelected ? selectedItems.removeAll(where: { [=10=] == item }) : selectedItems.append(item)
} label: {
Label(item, systemImage: isAlreadySelected ? "checkmark.circle.fill" : "")
}
}
}
}
}
}
}
}
演示该问题的视频:https://twitter.com/xmollv/status/1412397838319898637
谢谢!
编辑:
它似乎是一个 iOS 15 回归(至少在 Release Candidate 上),它在 iOS 14.6.
上运行良好
您可以使用任意 ID 的背景视图强制重绘上下文菜单。即:
@main
struct ContextMenuBugApp: App {
let availableItems = ["One", "Two", "Three", "Four", "Five"]
@State var selectedItems: [String] = []
func isAlreadySelected(_ item: String) -> Bool {
selectedItems.contains(item)
}
var body: some Scene {
WindowGroup {
List {
ForEach(availableItems, id: \.self) { item in
HStack {
Text("Row \(item), selected: \(isAlreadySelected(item) ? "true" : "false")")
}
.background(
Color.clear
.contextMenu {
ForEach(availableItems, id: \.self) { item in
Button {
isAlreadySelected(item) ? selectedItems.removeAll(where: { [=10=] == item }) : selectedItems.append(item)
} label: {
Label(item, systemImage: isAlreadySelected(item) ? "checkmark.circle.fill" : "")
}
}
}.id(selectedItems.count)
)
}
}
}
}
}
如果不行,你可以试试把id放到没有背景的contextMenu中(这可能是基于iOS的版本,以前不行,所以要小心,先测试一下iOS)
我遇到了一个问题,即显示的 Context Menu
显示了错误的数据,尽管下面的 List
显示了正确的数据。问题是,一旦触发第一项的上下文菜单上的操作,您将看到 List
如何重新呈现并显示正确的数据,但是如果您再次为第一项触发上下文菜单,它不会显示正确的状态。如果你打开第二个项目的上下文菜单,它会显示正确的状态,但如果你现在 select “Two”,并打开相同的上下文菜单,State
将是错误的(它'当它应该显示 1 和 2 时,我将只显示 1 selected,就像 List
显示它一样)。
感觉差了一个(比如显示以前的状态而不是最新的状态)我不确定这只是一个错误还是我用错了。
这是重现问题的代码片段:
@main
struct ContextMenuBugApp: App {
let availableItems = ["One", "Two", "Three", "Four", "Five"]
@State var selectedItems: [String] = []
var body: some Scene {
WindowGroup {
List {
ForEach(availableItems, id: \.self) { item in
HStack {
let isAlreadySelected = selectedItems.contains(item)
Text("Row \(item), selected: \(isAlreadySelected ? "true" : "false")")
}.contextMenu {
ForEach(availableItems, id: \.self) { item in
let isAlreadySelected = selectedItems.contains(item)
Button {
isAlreadySelected ? selectedItems.removeAll(where: { [=10=] == item }) : selectedItems.append(item)
} label: {
Label(item, systemImage: isAlreadySelected ? "checkmark.circle.fill" : "")
}
}
}
}
}
}
}
}
演示该问题的视频:https://twitter.com/xmollv/status/1412397838319898637
谢谢!
编辑:
它似乎是一个 iOS 15 回归(至少在 Release Candidate 上),它在 iOS 14.6.
上运行良好您可以使用任意 ID 的背景视图强制重绘上下文菜单。即:
@main
struct ContextMenuBugApp: App {
let availableItems = ["One", "Two", "Three", "Four", "Five"]
@State var selectedItems: [String] = []
func isAlreadySelected(_ item: String) -> Bool {
selectedItems.contains(item)
}
var body: some Scene {
WindowGroup {
List {
ForEach(availableItems, id: \.self) { item in
HStack {
Text("Row \(item), selected: \(isAlreadySelected(item) ? "true" : "false")")
}
.background(
Color.clear
.contextMenu {
ForEach(availableItems, id: \.self) { item in
Button {
isAlreadySelected(item) ? selectedItems.removeAll(where: { [=10=] == item }) : selectedItems.append(item)
} label: {
Label(item, systemImage: isAlreadySelected(item) ? "checkmark.circle.fill" : "")
}
}
}.id(selectedItems.count)
)
}
}
}
}
}
如果不行,你可以试试把id放到没有背景的contextMenu中(这可能是基于iOS的版本,以前不行,所以要小心,先测试一下iOS)