在选择器列表中添加搜索栏SwiftUI

k5hmc34c  于 2023-04-04  发布在  Swift
关注(0)|答案(2)|浏览(104)

我点击选择器,它将打开屏幕上的元素列表,我们可以添加搜索栏吗?
我实现了国家选择器,在国家列表中,我显示国家名称和国家代码,以便在列表屏幕上添加搜索栏,轻松找到国家。

struct ContentView: View {

    //All Country get from the plist with country Code and Coutnry Name.
    let countyList = Country().getAllCountyInfo()

    // Selected Country
    @State private var selectedCountry = 0

    var body: some View {

        NavigationView {
            Form {
                Picker(selection: $selectedCountry, label: Text("Country")) {

                    ForEach(countyList) { country in

                        HStack{
                            Text(country.countryName ?? "")
                            Spacer()
                            Text(country.countryCode ?? "")
                        }
                    }
                }
            }
            .navigationBarTitle("Select country picker")
        }

    }
}

通过运行上面的代码,它将打开一个国家列表,如上面的屏幕。
在上面的屏幕上(国家列表)。
如何添加搜索栏以过滤国家/地区数据?

jm81lzqq

jm81lzqq1#

我在我的博客文章中解决了这个问题:https://roddy.io/2020/09/07/add-search-bar-to-swiftui-picker/
创建UIViewRepresentable

struct SearchBar: UIViewRepresentable {

    @Binding var text: String
    var placeholder: String

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

        searchBar.placeholder = placeholder
        searchBar.autocapitalizationType = .none
        searchBar.searchBarStyle = .minimal
        return searchBar
    }

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

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

    class Coordinator: NSObject, UISearchBarDelegate {

        @Binding var text: String

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

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

然后很容易将其嵌入到Picker中:

struct FormView: View {

    let countries = ["Brazil", "Canada", "Egypt", "France", "Germany", "United Kingdom"]

    @State private var pickerSelection: String = ""
    @State private var searchTerm: String = ""
    
    var filteredCountries: [String] {
        countries.filter {
            searchTerm.isEmpty ? true : $0.lowercased().contains(searchTerm.lowercased())
        }
    }

    var body: some View {
        NavigationView {
            Form {
                Picker(selection: $pickerSelection, label: Text("")) {
                    SearchBar(text: $searchTerm, placeholder: "Search Countries")
                    ForEach(filteredCountries, id: \.self) { country in
                        Text(country).tag(country)
                    }
                }
            }
        }
    }
}
jljoyd4f

jljoyd4f2#

您可以添加一个TextField,它将作为选择器主体中的搜索栏:
搜索条形码:

struct SearchBar: View {
    @Binding var text: String
    @State var isEditing = false
    var body: some View {
        HStack {
            TextField("Search Countries", text: $text)
                .padding(7)
                .padding(.horizontal, 25)
                .background(Color.gray)
                .cornerRadius(8)
                .overlay(
                    HStack {
                        Image(systemName: "magnifyingglass")
                            .foregroundColor(.gray)
                            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                            .padding(.leading, 8)
                        if isEditing {
                            Button(action: {
                                text = ""
                            }) {
                                Image(systemName: "multiply.circle.fill")
                                    .foregroundColor(.gray)
                                    .padding(.trailing, 8)
                            }
                        }
                    }
                ).padding(.horizontal, 10)
                .onTapGesture {
                    isEditing = true
                }
            if isEditing {
                Button(action: {
                    UIApplication.shared.endEditing(true)
                    isEditing = false
                    text = ""
                }) {
                    Text("Cancel")
                }.padding(.trailing, 10)
                .transition(.move(edge: .trailing))
                .animation(.default)
            }
        }
    }
}

extension UIApplication {
    func endEditing(_ force: Bool) {
        self.windows
            .filter{$0.isKeyWindow}
            .first?
            .endEditing(force)
    }
}

extension View {
    func resignKeyboardOnDragGesture() -> some View {
        gesture(
            DragGesture()
                .onChanged { _ in
                    UIApplication.shared.endEditing(true)
                }
        )
    }
}

带搜索栏的选取器:

struct ContentView: View {
    @State var data: [String] = //your data
    @State var searchText = ""
    @State var selection: String?
    var displayedData: [String] {
        return data.filter({searchText.isEmpty ? true: $0.lowercased().contains(searchText.lowercased())})
    }
    var body: some View {
        Picker("Title", selection: $selection) {
            SearchBar(text: $searchText)
            ForEach(displayedData, id: \.self) { item in
                Text(item)
                    .tag(item)
            }.resignKeyboardOnDragGesture()
        }
    }
}

相关问题