在尝试添加点击和/或重新排序时,我注意到列表视图存在一些奇怪的问题/故障。 例如,我们假设以下示例代码:
List(selection: $selectedItem){
ForEach(items, id: \.self) { item in
Text(item.name)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.background(.red) //<-- background
.onTapGesture {
print("clicked on item")
}
}.onMove { from, to in
print("moving from \(from) to \(to)")
items.move(fromOffsets: from, toOffset: to)
}
}
}
如果它单击红色的任意位置,它就会起作用,但是如果我删除背景颜色或将其设置为
.clear
,它仅在我单击字母时才起作用。
当
.onTapGesture
不触发时,重新排序会起作用,所以如果我有 .red
背景,我必须找到微小的填充,然后单击并拖动它们才能触发,但如果我删除背景,它会很好地工作到处都是,除了当我直接点击 Text()
的字母时
如果我完全删除
.onTapGesture
重新排序按预期工作,那么,无论背景如何,我都可以拖放,我想这有点道理,因为 onTap 在层次上高于拖动...?
我的问题是,是否有一种更简单的方法可以在列表中同时进行单击操作和重新排序?
使用
.onChange(...)
和 selectedItem: UUID?
尝试这种不同的方法,
允许选择和重新排序。
示例代码:
struct ListView: View {
@State private var items = [TheItem(name: "item-1"),TheItem(name: "item-2"),TheItem(name: "item-3"),TheItem(name: "item-4")]
@State private var selectedItem: UUID? // <--- here
var body: some View {
List(selection: $selectedItem) {
ForEach(items) { item in
Text(item.name)
.background(.red)
}
.onMove { from, to in
print("----> moving from \(from) to \(to)")
items.move(fromOffsets: from, toOffset: to)
}
}
.onChange(of: selectedItem) { // <--- here
print("----> onChange selectedItem \(selectedItem)")
}
}
}
struct TheItem: Identifiable, Hashable {
let id = UUID()
var name: String
}
struct ContentView: View {
var body: some View {
ListView()
}
}