【问题标题】:SwiftUI Wrapped SearchBar Can't Dismiss KeyboardSwiftUI Wrapped SearchBar 无法关闭键盘
【发布时间】:2020-02-24 08:00:21
【问题描述】:

我正在使用 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 中的 List 中加载了一个 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)。斯威夫特用户界面。我已经在模拟器和 设备。任何指导将不胜感激。

【问题讨论】:

    标签: xcode uisearchbar swiftui uiviewrepresentable


    【解决方案1】:

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

    另外,当你清除文本时,你不应该设置searchBar.text = "",这是直接设置UISearchBars 文本属性的实例,而是清除你的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
        }
    }
    

    【讨论】:

      【解决方案2】:

      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)
          }
      }
      

      【讨论】:

      • 明白。这样可行。对于其他人 - 在我的情况下,我需要删除 searchBar.text = "" 行以保留 clearButton - 删除过滤器并返回完整列表所必需的。
      猜你喜欢
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 2020-06-20
      • 2020-02-20
      • 2020-02-09
      相关资源
      最近更新 更多