SwiftUI结合Core Data实现主列表滑动删除项及代码优化咨询
SwiftUI 滑动收藏功能优化方案
你当前的功能实现逻辑是完全可用的,以下是针对性的优化建议,可提升运行效率、可维护性与鲁棒性:
- 减少重复查询:原代码对同一个条目多次执行
contains(where:)遍历全量收藏数据,单次查询匹配结果后复用即可,减少冗余计算 - 简化取消收藏逻辑:取消收藏时无需遍历所有收藏条目,直接取出匹配到的目标条目删除即可,大幅降低时间复杂度
- 完善错误处理:原Core Data操作直接使用
try?忽略所有错误,增加错误捕获打印逻辑可大幅降低后期调试成本 - 规避类型精度隐患:如果业务中收藏的都是整数,建议将Core Data中Item实体的
number属性改为Int类型,避免Float转Int时可能出现的精度问题导致匹配失败 - 简化视图写法:系统图标无需嵌套在Text控件中,直接使用Image控件即可,代码更简洁
效果演示


优化后代码
struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.date, ascending: true)], animation: .default) private var items: FetchedResults<Item> var body: some View { TabView { // 主视图 // iOS 16+ 可替换为 NavigationStack 获得更新的特性支持 NavigationView { List { ForEach(1..<6, id: \.self) { currentNumber in HStack { Text("\(currentNumber)") Spacer() // 单次查询匹配的收藏项,后续逻辑复用该结果 let favoriteItem = items.first { Int($0.number) == currentNumber } if favoriteItem != nil { Image(systemName: "heart.fill") .foregroundColor(.blue) } } .swipeActions { let favoriteItem = items.first { Int($0.number) == currentNumber } Button(favoriteItem != nil ? "Unfavorite" : "Favorite") { if let item = favoriteItem { unfavorite(item) } else { favorite(Float(currentNumber)) } } .tint(favoriteItem != nil ? .red : .blue) } } } .navigationBarTitle("Numbers") } .tabItem { Image(systemName: "number") Text("Numbers") } // 收藏视图 NavigationView { List { ForEach(items, id: \.self) { item in HStack { Text(String(format: "%.0f", item.number)) Spacer() Image(systemName: "heart.fill") .foregroundColor(.blue) } } .onDelete { indexSet in indexSet.forEach { viewContext.delete(items[$0]) } saveContext() } } .navigationBarTitle("Favorites") } .tabItem { Image(systemName: "heart.fill") Text("Favorites") } } } func favorite(_ number: Float) { let fetchRequest: NSFetchRequest<Item> = Item.fetchRequest() fetchRequest.predicate = NSPredicate(format: "number = %f", number) do { let matchedItems = try viewContext.fetch(fetchRequest) guard matchedItems.isEmpty else { return } let newItem = Item(context: viewContext) newItem.number = number newItem.date = Date() saveContext() } catch { print("收藏查询失败:\(error.localizedDescription)") } } func unfavorite(_ item: Item) { viewContext.delete(item) saveContext() } // 抽离公共保存方法,统一处理错误 private func saveContext() { do { try viewContext.save() } catch { print("Core Data 保存失败:\(error.localizedDescription)") } } }
内容的提问来源于stack exchange,提问作者cole
相关产品推荐
相关产品推荐

