过滤列表时SwiftUI .onDelete错误的索引

问题描述

这是我的代码

import SwiftUI

struct IngredientsList: View {
    @EnvironmentObject var ingredientsstore: IngredientEdit
    @State private var searchText = ""
    
    var searchResults: [Ingredient] {
        if searchText.isEmpty {
            return ingredientsstore.items
        } else {
            return ingredientsstore.items.filter {
                $0.name.lowercased().contains(searchText.lowercased()) }
        }
    }
    
    var body: some View {
        NavigationView {
            List {
                ForEach (searchResults) { ingredient in
                    NavigationLink (destination: IngredientDetail(ingredient: ingredient)) {
                        IngredientRow(ingredient: ingredient)
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .searchable(text: $searchText,placement: .navigationBarDrawer(displayMode: .automatic))
            .navigationTitle("Ingredients")
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
    
    func deleteItems(at offsets: IndexSet) {
        withAnimation {
                ingredientsstore.items.remove(atOffsets: offsets)

        }
    }
    
}

如果 searchText 为空,则效果很好,但如果列表被过滤,则不起作用。调试器显示 'offsets' 总是包含来自过滤列表的索引(我在屏幕上看到的),例如它是成分商店.items[1] 但是 .remove 方法会将 [1] 传递给 Observedobject 其中 [1]将对应于完全不同的项目,因此将从数组中删除错误的项目:( 换句话说,过滤列表包含具有绝对值的索引,据我所知。 您的治疗将不胜感激。 谢谢。

解决方法

ingredientsStore.items.remove(atOffsets: offsets)

这里的偏移量是搜索结果的索引。

所以你应该从 searchResults 中获取 Ingredient 项,然后从 ingredientsStore.items 中删除它。

试试这个:

for offset in offsets{
    if let index = ingredientsStore.items.firstIndex(searchResults[offset]) {
        ingredientsStore.items.remove(at: index)
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...