I would like to make a search bar in this view but I am wondering how I go about calling my completion block which fills the data. At the moment I have the completion block in .onAppear
but when I go to add a search bar, the data will only be loaded once in .onAppear
and so when I search, the results won’t update. Here is my view
struct CocktailList: View {
@State private var cocktails: [Cocktail]
@State private var searchText = ""
var body: some View {
VStack {
NavigationView {
List(cocktails, id: .idDrink) { cocktail in
NavigationLink(destination: CocktailDetail(fromCocktail: cocktail)) {
CocktailRow(fromCocktail: cocktail)
}
}
.navigationTitle("Search Results")
}.onAppear {
requestCocktail(searchTerm: "daiquiri") { cocktails in
self.cocktails = cocktails
}
}
}
}
init() {
self.cocktails = []
}
}
How do I call requestCocktail()
upon the update of the searchText and what is the best way to integrate a simple search bar?
2
Answers
I gave you an example with a TextField and different related actions:
onCommit
,onEditing
, when the text changes, when the text hasn’t changed for 1 second. It’s up to you to choose when you want to executerequestCocktail()
.Start with a clear separation of concerns in mind:
(Prerequisite: iOS 15)
It displays your items and provides a "search bar".
Note, that it does not change its view state and that is uses a binding for the query string to communicate it with its parent view.
I also omitted some details from the original, since it is not relevant to the question.
Here, the View Model is "event driven" and uses Combine under the hood. It also resembles a "extended finite state machine" where "input" are the inputs of the FSM. But, really, the is pretty irrelevant – it’s an implementation detail – and just an example how you can implement a view model.
With an FSS you need an
update
function. It is a pure function solely responsible to generate a new View State from the current view state and the event.