Swiftui 删除项目时列表的奇怪行为
删除项目时,我遇到一个奇怪的列表行为 数据模型Swiftui 删除项目时列表的奇怪行为,swiftui,Swiftui,删除项目时,我遇到一个奇怪的列表行为 数据模型 class Item: Identifiable, ObservableObject { let id = UUID() @Published var name: String internal init(name: String) { self.name = name } } 视图模型 class ListViewModel: ObservableObject { @Publis
class Item: Identifiable, ObservableObject {
let id = UUID()
@Published var name: String
internal init(name: String) {
self.name = name
}
}
视图模型
class ListViewModel: ObservableObject {
@Published var items: [Item]
internal init(items: [Item]) {
self.items = items
}
internal init() {
self.items = [Item(name: "A"), Item(name: "B"), Item(name: "C"), Item(name: "D")]
}
}
看法
现在是奇怪的行为。点击一行的按钮:
struct ContentView: View {
@ObservedObject var viewModel = ListViewModel()
var body: some View {
List(viewModel.items, id: \.id) { item in
Row(item: item) { action in
switch action {
case .delete:
if let idx = viewModel.items.firstIndex(where: { $0.id == item.id }) {
viewModel.items.remove(at: idx)
}
case .edit:
break
default:
break
}
}
}
}
}
我使用ForEach的方式是否错误?仅使用索引而不使用可识别值的
ForEach
会导致此类问题。如果可以,请始终使用唯一ID。
struct ContentView: View {
@ObservedObject var viewModel = ListViewModel()
var body: some View {
List {
ForEach(0 ..< viewModel.items.count, id: \.self) { idx in
// HStack {
// Text("\(viewModel.items[idx].name)")
// Spacer()
// Button("Edit") {
// // To be done
// }
// .buttonStyle(BorderlessButtonStyle())
// Button("Delete") {
// viewModel.items.remove(at: idx)
// }
// .buttonStyle(BorderlessButtonStyle())
// }
Row(item: viewModel.items[idx]) { action in
switch action {
case .delete:
viewModel.items.remove(at: idx)
case .edit:
// To be done
break
default:
break
}
}
}
}
}
}
enum ActionType {
case new
case edit
case delete
case cancel
}
struct Row: View {
@State var item: Item
var action: (_ type: ActionType) -> Void
var body: some View {
HStack {
Text("\(item.name)")
Spacer()
Button("Edit") {
action(.edit)
}
.buttonStyle(BorderlessButtonStyle())
Button("Delete") {
action(.delete)
}
.buttonStyle(BorderlessButtonStyle())
}
}
}
struct ContentView: View {
@ObservedObject var viewModel = ListViewModel()
var body: some View {
List(viewModel.items, id: \.id) { item in
Row(item: item) { action in
switch action {
case .delete:
if let idx = viewModel.items.firstIndex(where: { $0.id == item.id }) {
viewModel.items.remove(at: idx)
}
case .edit:
break
default:
break
}
}
}
}
}