SwiftUI包装的SearchBar无法关闭键盘

时间:2019-10-29 04:10:29

标签: xcode uisearchbar swiftui uiviewrepresentable

我正在使用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)。 SwiftUI。我已经在模拟器和 设备。任何指导将不胜感激。

2 个答案:

答案 0 :(得分:1)

未调用searchBarCancelButtonClicked的原因是因为它在MySearchBar中,但是您已经将Coordinator设置为搜索栏的代表。如果将searchBarCancelButtonClicked函数移到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)
    }
}

答案 1 :(得分:1)

searchBarCancelButtonClicked调用将被传递给UISearchBar的委托,该委托已设置为Coordinator,因此将func searchBarCancelButtonClicked放在那里。

此外,在清除文本时,您不应该设置searchBar.text = "",它直接设置UISearchBar的text属性的实例,而要清除Coordinators属性text。这样,您的SwiftUI视图将由于@Binding属性包装器而注意到更改,并且知道该更新了。

以下是“ 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
    }
}