You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS15 SwiftUI下如何正确过滤SectionedFetchRequest实现搜索功能

解决方案

你完全不需要实现复杂的RandomAccessCollection协议,只要构造一个轻量的临时结构体承接过滤后的分栏数据即可,十几行代码就能解决问题:

  1. 首先定义一个仅用于展示的分栏结构体,遵守Identifiable协议即可满足ForEach的使用要求:
struct FilteredSection: Identifiable {
    let id: String
    let items: [Item]
}
  1. 修改你的过滤方法,返回上述结构体数组:
private func getFilteredSections() -> [FilteredSection] {
    let cleanedFilter = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
    guard !cleanedFilter.isEmpty else {
        // 搜索内容为空时直接返回原始数据映射结果
        return mySections.map { section in
            FilteredSection(id: section.id, items: section.map { $0 })
        }
    }
    
    func checkItem(_ item: Item) -> Bool {
        return item.name.localizedCaseInsensitiveContains(cleanedFilter) 
    }
    
    return mySections.compactMap { section in
        // 先过滤当前分栏下符合搜索条件的条目
        let matchedItems = section.filter(checkItem)
        // 没有符合条件的条目时直接丢弃当前分栏
        guard !matchedItems.isEmpty else { return nil }
        return FilteredSection(id: section.id, items: matchedItems)
    }
}
  1. 替换原有List的数据源即可,布局逻辑不需要做任何改动:
List {
    ForEach(getFilteredSections()) { section in
        Section(header: Text(section.id)) {
            // 如果你的Item未遵守Identifiable,这里改为ForEach(section.items, id: \.objectID)
            ForEach(section.items) { item in
                Text(item.name)
            }
        }
    }
}
.searchable(text: $searchText)

方案优势

  • 完全避开了修改SectionedFetchRequest谓词触发的视图重初始化问题,搜索状态保存在当前视图的@State变量中,跳转详情页返回后不会丢失,也不会出现详情页意外弹出的问题
  • 代码复杂度极低,不需要适配任何系统底层协议
  • 保留了原有分栏的id属性,完全不影响原有分栏标题的展示逻辑

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:15:00