【问题标题】:SwiftUI Catch the Picker value from another viewSwiftUI 从另一个视图中捕获 Picker 值
【发布时间】:2021-02-08 08:46:22
【问题描述】:

我需要在选择器中添加搜索栏和 nil 值。我想创建一个自定义选择器并在任何地方使用它以避免代码重复。我能够使用 thisthis 代码创建选择器,但我找不到如何捕获我在另一个视图中选择的值。

这段代码帮助我在选择器中进行搜索。

    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 中捕获选定的项目(可选)?

【问题讨论】:

    标签: swiftui picker


    【解决方案1】:

    使用@Binding绑定你的物品。

    struct CustomPicker<Item>: View where Item: Hashable {
        let items: [Item]
        let title: String
        let text: KeyPath<Item, String>
        let needOptional: Bool
        let needSearchBar: Bool
        
        @Binding var item: Item? // <--Here
        @State var searchText: String = ""
        
        
        //-----Other code---------//
    

    并在内容视图中使用@State 获取所选值。

    struct ContentView: View {
        
        @State private var selectedItem: Country? //<-- Here
        
        private let countryArray: [Country] = [.init(name: "A"), .init(name: "B")]
        
        var body: some View {
            Form {
                CustomPicker(items: countryArray, title: "Country", text: \Country.name, needOptional: true, needSearchBar: true, item: $selectedItem) // <-- Here
                if let selectedItem = selectedItem {
                    Text(selectedItem.name)
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢,我试过@Binding var item: Item? = 每次都为零。
    猜你喜欢
    • 2022-06-15
    • 2020-06-21
    • 1970-01-01
    • 2022-11-22
    • 2021-10-15
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多