I got a re-usable searchbar in a separate view that looks like this:
struct SearchBar: View {
@Binding var searchText: String
@Binding var isSearching: Bool
var body: some View {
HStack {
HStack {
TextField("Search terms here", text: $searchText)
}
.onTapGesture(perform: {
isSearching = true
})
.overlay(
HStack {
Image(systemName: "magnifyingglass")
if isSearching {
Button(action: { searchText = "" }, label: {
Image(systemName: "xmark.circle.fill")
})
}
}
)
if isSearching {
Button(action: {
isSearching = false
searchText = ""
}, label: {
Text("Cancel")
})
}
}
}
}
And I'm using the SearchBar
in multiple views, like this:
SearchBar(searchText: $textFieldSearch, isSearching: $isSearching)
Is there a way to override/append the functionality of the cancel button:
Button(action: {
isSearching = false
searchText = ""
// pass more functionality here dynamically
},
label: {
Text("Cancel")
})
In some Views, I need to do some additional stuff besides clearing the searchText
field and setting isSearching
to false.
CodePudding user response:
You can use closure. Here I created one cancel button closure action and set it as optional.
struct SearchBar: View {
@Binding var searchText: String
@Binding var isSearching: Bool
var cancel: (() -> Void)? // <== Here
var body: some View {
HStack {
HStack {
TextField("Search terms here", text: $searchText)
}
.onTapGesture(perform: {
isSearching = true
})
.overlay(
HStack {
Image(systemName: "magnifyingglass")
if isSearching {
Button(action: { searchText = "" }, label: {
Image(systemName: "xmark.circle.fill")
})
}
}
)
if isSearching {
Button(action: {
isSearching = false
searchText = ""
cancel?() // <== Here
}, label: {
Text("Cancel")
})
}
}
}
}
Usage
SearchBar(searchText: $textFieldSearch, isSearching: $isSearching)
SearchBar(searchText: $textFieldSearch, isSearching: $isSearching) {
// Cancel Action
}
CodePudding user response:
If you need addtional action then you can inject onCancel
side effect like
struct SearchBar: View {
@Binding var searchText: String
@Binding var isSearching: Bool
var onCancel: () -> Void = {} // << default does nothing
...
if isSearching {
Button(action: {
isSearching = false
searchText = ""
onCancel() // << here !!
}, label: {
Text("Cancel")
})
}
and use either in default way as you did or providing side effect, like
SearchBar(searchText: $textFieldSearch, isSearching: $isSearching) {
// side effect is here
}