首页 > 解决方案 > SwiftUI - 在列表标题中搜索

问题描述

我正在尝试使用 SwiftUI 从 UITableView 重新创建每个人都知道的内容:tableview 标题中的一个简单搜索字段:

表格视图标题中的简单搜索字段

但是,SwiftUI 中的列表视图甚至似乎没有添加页眉或页脚的方法。您可以将带有 TextField 的标题设置为如下部分:

@State private var searchQuery: String = ""

var body: some View {

List {
    Section(header:
        Group{
            TextField($searchQuery, placeholder: Text("Search"))
                                .background(Color.white)
            }) {
                  ListCell()
                  ListCell()
                  ListCell()
                }

    }
}

但是,我不确定这是否是最好的方法,因为:

  1. 从 UITableView 向下滚动时,标题不会隐藏。
  2. SearchField 看起来不像我们熟悉和喜爱的搜索字段。

有没有人找到一个好的方法?我不想依赖 UITableView。

标签: uitableviewsearchtextfieldswiftui

解决方案


Xcode 13 / SwiftUI 3

您现在可以.searchable用来制作列表...可搜索!

struct ContentView: View {

    @State private var searchQuery: String = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(Array(1...100)
                            .map { "\($0)" }
                            .filter { searchQuery.isEmpty ? true : $0.contains(searchQuery) }
                        ,id: \.self) { item in
                    Text(verbatim: item)
                }
            }
            .navigationTitle("Fancy Numbers")
            .searchable(text: $searchQuery)
        }
    }

}

搜索栏似乎只有在List嵌入NavigationView.


Xcode 12,SwiftUI 1/2

您可以移植UISearchBar到 SwiftUI。

(有关这方面的更多信息,请参阅出色的 WWDC 2019 演讲 -集成 SwiftUI

struct SearchBar: UIViewRepresentable {

    @Binding var text: String

    class Coordinator: NSObject, UISearchBarDelegate {

        @Binding var text: String

        init(text: Binding<String>) {
            _text = text
        }

        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            text = searchText
        }
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(text: $text)
    }

    func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {
        let searchBar = UISearchBar(frame: .zero)
        searchBar.delegate = context.coordinator
        return searchBar
    }

    func updateUIView(_ uiView: UISearchBar,
                      context: UIViewRepresentableContext<SearchBar>) {
        uiView.text = text
    }
}

并像这样使用它:

struct ContentView: View {

    @State private var searchQuery: String = ""

    var body: some View {

        List {
            Section(header: SearchBar(text: self.$searchQuery)) {
                ForEach(Array(1...100).filter {
                    self.searchQuery.isEmpty ?
                        true :
                        "\($0)".contains(self.searchQuery)
                }, id: \.self) { item in
                    Text("\(item)")
                }
            }
        }
    }
}

这是正确的搜索栏,但它不会隐藏 - 我相信我们将能够在某个时候通过 SwiftUI API 做到这一点。

看起来像这样

在此处输入图像描述


推荐阅读