【发布时间】:2021-02-08 08:46:22
【问题描述】:
我需要在选择器中添加搜索栏和 nil 值。我想创建一个自定义选择器并在任何地方使用它以避免代码重复。我能够使用 this 和 this 代码创建选择器,但我找不到如何捕获我在另一个视图中选择的值。
这段代码帮助我在选择器中进行搜索。
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
}
}
}
这是我创建的自定义选择器。
struct CustomPicker<Item>: View where Item: Hashable {
let items: [Item]
let title: String
let text: KeyPath<Item, String>
let needOptional: Bool
let needSearchBar: Bool
@State var item: Item? = nil
@State var searchText: String = ""
var filteredItems: [Item] {
items.filter {
searchText.isEmpty ? true : $0[keyPath: text].lowercased().localizedStandardContains(searchText.lowercased())
}
}
var body: some View {
Picker(selection: $item, label: Text(title)) {
if needSearchBar {
SearchBar(text: $searchText, placeholder: "Search")
.padding(.horizontal, -12)
}
if needOptional {
Text("[none]").tag(nil as Item?)
.foregroundColor(.red)
}
ForEach(filteredItems, id: \.self) { item in
Text(item[keyPath: text])
.tag(item as Item?)
}
}
.onAppear{
searchText = ""
}
}
}
用法
国家模式示例
struct Country: Codable, Identifiable, Hashable {
let id = UUID()
let name: String
enum CodingKeys: String, CodingKey {
case id, name
}
}
在内容视图中
Form {
CustomPicker(items: countryArray, title: "Country", text: \Country.name, needOptional: true, needSearchBar: true)
}
如何在 ContentView 中捕获选定的项目(可选)?
【问题讨论】: