Ok, still not sure I understood the flow, but let's try...
Having some assumptions (mentioned in comments) the approach might be as follows (original code is not testable so answer was prepared just here - might be typos, adapting is on you, but idea should be clear):
struct AuthorSearchBar: View {
@StateObject var service = AuthorService()
@Binding var isCancel: Bool
var body: some View {
VStack(spacing: 0) {
HStack {
Image(systemName: "magnifyingglass")
TextField("Search", text: $service.searchText)
.padding()
}
.onReceive(Just(service.searchText)) { text in
if !text.isEmpty { // assuming search only for existed text
service.fetchData(for: text)
}
}
.onReceive(Just(self.isCancel)) { canceled in
if canceled {
// assuming needed to send on explicit cancel
service.fetchData(for: "")
}
}
}
}
}
// pass what should be sent via argument instead of use property
func fetchData(for text: String) {
let parameters = ["index": "authors", "query": "(text)" ]
...
}
Alternate: no changes to fetchData
, but in that case it is not possible to separate case with empty string as entered and on canceled (though it is not clear if it does matter).
HStack {
Image(systemName: "magnifyingglass")
TextField("Search", text: $service.searchText)
.padding()
}
.onReceive(Just(service.searchText)) { text in
service.fetchData()
}
.onReceive(Just(self.isCancel)) { canceled in
if canceled {
service.searchText = "" // << this activates above onReceive
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…