SwiftUI-搜索列表头

时间:2019-06-15 09:10:57

标签: uitableview search textfield swiftui

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

A simple search field in the header of the 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。

4 个答案:

答案 0 :(得分:5)

您可以将UISearchBar移植到SwiftUI。

(有关此问题的更多信息,请参见WWDC 2019精彩演讲-Integrating 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)
                }) { item in
                    Text("\(item)")
                }
            }
        }
    }
}

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

看起来像这样

enter image description here

答案 1 :(得分:2)

也许是一个起点。考虑使用ZStack来使滚动视图的滚动效果消失。


struct ContentView : View {
    @State var search: String

    var body: some View {
        NavigationView {
            HStack {
                Image(systemName: "magnifyingglass")
                    .padding(.leading, 10.0)
                TextField($search, placeholder: Text("Search"))
                    .padding(.vertical, 4.0)
                    .padding(.trailing, 10.0)
            }
                .border(Color.secondary, width: 1, cornerRadius: 5)
                .padding()
            List {
                ForEach(0...100) { e in
                    Text("Item \(e)")
                }
            }
                .navigationBarTitle(Text("TEST"))
        }
    }
}

Screenshot

答案 2 :(得分:1)

我使用SwiftUI实现了国家选择器项目Columbus。我实现了自定义发布者CountryListViewModel,并将其与文本字段关联。这样,当所有操作完成时,我可以键入,搜索数据源,过滤出结果/防反跳和更新表视图。效果很好?

https://github.com/Blackjacx/Columbus/tree/swift-ui/Source/Classes

答案 3 :(得分:1)

2021 — Xcode 13 / SwiftUI 3

原生 SwiftUI 解决方案:

List {
    ForEach(0..<5) {
        index in
            Text("item \(index)")
        }
    }
}
.searchable(text: .constant("search_value")) // should be a Binding