微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift 搜索对象

如何解决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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。