3

我正在使用 UIViewRepresentable 向 SwiftUI 项目添加搜索栏。搜索栏用于搜索主列表 - 我已经设置了搜索逻辑并且工作正常,但是我无法将键盘编码为在取消搜索时消失。取消按钮没有响应。如果我单击文本字段 clearButton,则搜索结束并出现完整列表,但键盘不会消失。如果我取消注释 textDidChange 中的 resignFirstResponder 行,则行为与预期一致,只是键盘在每个字符后消失。

这是搜索栏:

import Foundation
import SwiftUI

struct MySearchBar: UIViewRepresentable {
    @Binding var sText: String

    class Coordinator: NSObject, UISearchBarDelegate {
        @Binding var sText: String

        init(sText: Binding<String>) {
            _sText = sText
        }

        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            sText = searchText
            //this works for EVERY character
            //searchBar.resignFirstResponder()
        }
    }

    func makeCoordinator() -> MySearchBar.Coordinator {
        return Coordinator(sText: $sText)
    }

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

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

    func searchBarCancelButtonClicked(searchBar: UISearchBar) {
        //this does not work
        searchBar.text = ""
        //none of these work

        searchBar.resignFirstResponder()
        searchBar.showsCancelButton = false
        searchBar.endEditing(true)
    }
}

我在列表中的 SwiftUI 中加载了一个 MySearchBar。

var body: some View {
    NavigationView {
        List {
            MySearchBar(sText: $searchTerm)
            if !searchTerm.isEmpty {

                ForEach(Patient.filterForSearchPatients(searchText: searchTerm)) { patient in
                    NavigationLink(destination: EditPatient(patient: patient, photoStore: self.photoStore, myTextViews: MyTextViews())) {
                        HStack(spacing: 30) {

                        //and the rest of the application

Xcode 版本 11.2 beta 2 (11B44)。斯威夫特用户界面。我已经在模拟器和设备上进行了测试。任何指导将不胜感激。

4

2 回答 2

3

没有被调用的原因searchBarCancelButtonClicked是因为它在MySearchBar但您已将 设置Coordinator为搜索栏委托。如果将searchBarCancelButtonClickedfunc 移动到Coordinator,它将被调用。

这是协调器的外观:

class Coordinator: NSObject, UISearchBarDelegate {
    @Binding var sText: String

    init(sText: Binding<String>) {
        _sText = sText
    }

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

    func searchBarCancelButtonClicked(searchBar: UISearchBar) {

        searchBar.text = ""

        searchBar.resignFirstResponder()
        searchBar.showsCancelButton = false
        searchBar.endEditing(true)
    }
}
于 2019-10-29T04:20:47.673 回答
2

The searchBarCancelButtonClicked call will be passed to the UISearchBars delegate, which is set to Coordinator, so put func searchBarCancelButtonClicked there instead.

Also, when you are clearing the text you shouldnt set searchBar.text = "", which is setting the instance of UISearchBars text property directly, but instead clear your Coordinators property text. In that way your SwiftUI View will notice the change because of the @Binding property wrapper, and know that it´s time to update.

Here is the complete code for `MySearchBar´:

import UIKit
import SwiftUI

struct MySearchBar : 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
            searchBar.showsCancelButton = true
        }

        func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
            text = ""
            searchBar.showsCancelButton = false
            searchBar.endEditing(true)
        }
    }

    func makeCoordinator() -> SearchBar.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
    }
}
于 2020-01-14T09:24:30.317 回答