SwiftUI 包装的 SearchBar 无法关闭键盘
SwiftUI Wrapped SearchBar Can't Dismiss Keyboard
我正在使用 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)。斯威夫特用户界面。我已经在模拟器和
设备。任何指导将不胜感激。
未调用 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
委托,因此将 func searchBarCancelButtonClicked
放在那里。
此外,当您清除文本时,您不应该设置 searchBar.text = ""
,这是直接设置 UISearchBar
s 文本 属性 的实例,而是清除您的协调器 属性 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
}
}
我正在使用 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)。斯威夫特用户界面。我已经在模拟器和 设备。任何指导将不胜感激。
未调用 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
委托,因此将 func searchBarCancelButtonClicked
放在那里。
此外,当您清除文本时,您不应该设置 searchBar.text = ""
,这是直接设置 UISearchBar
s 文本 属性 的实例,而是清除您的协调器 属性 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
}
}