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

SwiftUI中基于Model实现列表搜索的方法求助

解决SwiftUI List结合外部Model的搜索功能问题

核心思路

你的需求是基于外部定义的FavoriteModel和FavoriteElements实现分组列表的搜索,关键是要过滤分组内的元素,并只保留包含匹配元素的分组,同时处理搜索文本为空时显示全部内容的场景。

修改后的完整代码

ContentView.swift

import SwiftUI

struct ContentView: View {
    @State private var searchText: String = ""
    
    // 计算属性:根据搜索文本动态过滤数据
    private var filteredFavorites: [FavoriteModel] {
        guard !searchText.isEmpty else {
            return myFavorites // 搜索文本为空时返回全部数据
        }
        // 转换为小写,实现不区分大小写的搜索
        let lowercasedSearch = searchText.lowercased()
        // 过滤每个分组:只保留包含匹配元素的分组
        return myFavorites.map { model in
            let filteredElements = model.elements.filter {
                $0.name.lowercased().contains(lowercasedSearch)
            }
            return FavoriteModel(id: model.id, title: model.title, elements: filteredElements)
        }.filter { !$0.elements.isEmpty } // 移除没有匹配元素的空分组
    }
    
    var body: some View {
        NavigationView {
            List {
                // 遍历过滤后的分组数据
                ForEach(filteredFavorites) { favorite in
                    Section(header: Text(favorite.title)) {
                        ForEach(favorite.elements) { element in
                            NavigationLink(destination: DetailsView(chosenFavoriteElement: element)) {
                                Text(element.name)
                            }
                        }
                    }
                }
            }
            .navigationBarTitle("Favorite Book App")
            .navigationBarTitleDisplayMode(.inline)
            .searchable(text: $searchText)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

FavoriteModel.swift(无需修改)

import Foundation

struct FavoriteModel : Identifiable {
    var id = UUID()
    var title : String
    var elements : [FavoriteElements]
}

struct FavoriteElements : Identifiable {
    var id = UUID()
    var name : String
    var imageName : String
    var description : String
}

let macOS = FavoriteElements(name: "MacOS", imageName: "macosventura", description: "MacOS 13 Ventura")
let windows = FavoriteElements(name: "Windows", imageName: "windows11", description: "Windows 11")

let borusanMannesmann = FavoriteElements(name: "Borusan Mannesmann", imageName: "borusanlogo", description: "Borusan Mannesmann Boru A.Ş.")
let aselsan = FavoriteElements(name: "Aselsan", imageName: "aselsan", description: "Aselsan Askeri Sanayi")

let favoriteOperatingSystems = FavoriteModel(title: "Favorite Operating Systems", elements: [macOS, windows])
let favoriteCompanies = FavoriteModel(title: "Favorite Companies", elements: [borusanMannesmann, aselsan])

let myFavorites = [favoriteOperatingSystems, favoriteCompanies]

关键修改点说明

  1. 替换状态变量为计算属性:用filteredFavorites计算属性替代原有的filteredText,无需手动监听searchText变化,SwiftUI会自动在searchText更新时重新计算过滤结果。
  2. 不区分大小写的搜索:将搜索文本和元素名称都转换为小写,确保搜索结果不受大小写影响。
  3. 过滤逻辑分层:
    • 先过滤每个分组内的elements,只保留名称包含搜索文本的元素;
    • 再过滤整个分组列表,移除没有匹配元素的空分组,避免显示空的Section。
  4. 保持原有分组结构:通过映射原FavoriteModel生成新的过滤后模型,保留原有分组的标题和ID,确保Section的展示逻辑和原代码一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:00:11