I've implemented a simple UISearchBar, however, the "X" button just works when I call the search bar directly. Why is that?
Here is my code:
UISearchBar
struct SearchBarView: View, 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
}
}
func makeCoordinator() -> SearchBarView.Coordinator {
return Coordinator(text: $text)
}
func makeUIView(context: UIViewRepresentableContext<SearchBarView>) -> UISearchBar {
let searchBar = UISearchBar(frame: .zero)
searchBar.delegate = context.coordinator
searchBar.autocapitalizationType = .none
searchBar.enablesReturnKeyAutomatically = true
searchBar.showsSearchResultsButton = true
searchBar.setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
searchBar.searchTextField.backgroundColor = UIColor.init(red: 239/255, green: 239/255, blue: 239/255, alpha: 1)
searchBar.isTranslucent = true
searchBar.placeholder = "Pesquisar"
return searchBar
}
func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBarView>) {
uiView.text = text
}
}
My TopBarView in another file
struct TopBarView: View {
@EnvironmentObject var environmentController : EnvironmentController
var body: some View {
HStack() {
Button(action: {
self.environmentController.environment.showMenu.toggle()
}) {
Image(systemName: "line.horizontal.3")
.background(
RoundedRectangle(cornerRadius: 8.0)
.foregroundColor(Color.init(red: 239/255, green: 239/255, blue: 239/255))
.frame(width: 36, height: 36, alignment: .center))
.foregroundColor(.black)
.imageScale(.large)
.font(.subheadline)
.frame(width: 40, height: 40, alignment: .center)
}
SearchBarView(text: self.$environmentController.environment.searchText)
}
.padding(.top, 30)
.padding(.all)
}
}
My MainView, also in another file
struct NextDeparturesView: View {
@ObservedObject var userSettingsController = UserSettingsController()
@EnvironmentObject var environmentController : EnvironmentController
@State private var showMap = false
var body: some View {
VStack() {
//If showUserActionSheet is false or showMap is true, display the menu button, the search bar and the map
if(!self.userSettingsController.showUserCityActionSheet || showMap) {
MapView()
.overlay(
TopBarView(),
alignment: .top)
.edgesIgnoringSafeArea(.top)
.onTapGesture {
if(self.environmentController.environment.showMenu) {
self.environmentController.environment.showMenu.toggle()
}
}
}
}
So, if in my MainView I call the SearchBarView directly, the "x" button works. However, if I use the TopBarView, as in the code, the "x" button stops working. It may also be worth mentioning that writing in the search bar always works, it is just the "x" button that stops working.
I'm new to swift, what am I missing?
Thanks
EDIT
I still can't figure this out, but I guess it stops working when inside the overlay. In my MainView, if I move the TopBarView() call outside the overlay, it works.
EDIT2
So, if I add allowHitTesting(false) to my MainView overlay, the UISearchBar starts working, however, the menu button stops... If you have only one action in your overlay, this might be the solution for you.
Ok, so if anyone finds themselves in the same position as me and can't find a solution, the only way I got it to work was to abandon the overlay and develop a more complex view using ZStack.
In the question edits you can see what I tried before, maybe it will help you.
I'll accept this as the answer, however, if someone eventually comes up with a better solution, I will change it.