SwiftUI Wrapped SearchBar не может закрыть клавиатуру
Я использую UIViewRepresentable, чтобы добавить панель поиска в проект SwiftUI. Панель поиска предназначена для поиска в основном списке - я настроил логику поиска, и она работает нормально, однако мне не удалось закодировать исчезновение клавиатуры при отмене поиска. Кнопка Отмена не реагирует. Если я щелкну текстовое поле clearButton, поиск будет завершен и появится полный список, но клавиатура не исчезнет. Если я раскомментирую строку resignFirstResponder в textDidChange, поведение будет таким, как ожидалось, за исключением того, что клавиатура исчезает после каждого символа.
Вот строка поиска:
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)
}
}
И я загружаю MySearchBar в SwiftUI в список.
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 бета 2 (11B44). SwiftUI. Я тестировал на симуляторе и на устройстве. Любое руководство будет оценено.
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)
}
}
В searchBarCancelButtonClicked
звонок будет передан UISearchBar
s делегат, который установлен как координатор, поэтому поместите func searchBarCancelButtonClicked
вместо этого.
Кроме того, когда вы очищаете текст, вы не должны устанавливать searchBar.text = ""
, который устанавливает экземпляр UISearchBar
s text свойство напрямую, но вместо этого очистите свойство Coordinators text
. Таким образом ваш SwiftUI View заметит изменение из-за@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
}
}