Swift 搜索对象

问题描述

我想创建一个搜索功能,以便用户能够在我的应用中搜索列表。

Screenshot of the SearchBar

我像这样初始化这个赛道列表:

 var tracks: [Track] = tracksData

并像这样实现搜索

NavigationSearch(text: $searchText,searchResultsContent: {
                vstack(alignment: .leading) {
                    Text("Search Results for \(searchText)")
                        .fontWeight(.bold)
                        .padding([.top,.bottom])

                    Divider()
                    
                    ForEach(Track.filter { self.searchText.isEmpty ? true : $0.contains(self.searchText) },id: \.self) { fruit in
                        Text(fruit)
                        Divider()
                    }

                    Spacer()
                }
                .padding()
            })

这是 Mark van Wijnen 的 medium article

但我总是收到如下所示的错误

Screenshot of the code snippet

Screenshot of the build error

我知道错误是由我用于轨道对象的数据类型引起的,因为 Mark van Wijnen 使用了一个简单的字符串数组,但我无法修复此搜索功能,以便它能够搜索我的对象数组。我希望有人能帮助我解决这个问题。 提前致谢

链接到包含示例数据的包: https://workupload.com/file/cbky5ucgM26

解决方法

你离我太近了!将代码分开会产生更好的错误,你会发现它。如果使用 self 作为 id,则 ForEach 要求项目是可散列的。在 self 中使用 Track 的 id 属性可能会清除该错误。但是,需要一些工作才能实现,所以这里是重构的代码。

将搜索过滤器拆分到 TrackModel 中,以便可以搜索多个字段:

func search(_ query: String) -> Bool {
    let searchable = [title,headline,description] + details

    return searchable.filter({ $0.contains(query) }).count > 0
}

接下来在TrackView3中添加一个计算属性来封装列表:

var filtered : [Track] {
    if searchText.isEmpty {
        return tracks
    } else {
        return tracks.filter({ $0.search(searchText) })
    }
}

现在 ForEach 没有所有的搜索内容及其整洁的形式:

ForEach(filtered,id: \.id) { track in
 TrackDetailView(tracks: track)
 Divider()

}

Paul Hudson 最近制作了一个视频,其中提供了更好的 Swift Views 技巧。他介绍了在计算属性中封装代码。它使代码更清晰,并使编码人员免受声明树中的错误(错误并不总是有帮助)。 5 Steps to Better SwiftUI Views

相关问答

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