I'm using a wrapper around UISearchBar
and I'm seeing a different behavior when passing a @Published
property into this SearchBar
wrapper versus a TextField
.
Both are updating the @ObservedObject var query = Query()
class @Published var input
property as expected but only the TextField
is then updating the SearchSheet
view. I would like for the view to be updated when input
has been changed in SearchBar
similarly to how it is updated from TextField
.
Edit: I've updated my question to include the ContentView
where it looks like this issue is specific to when the sheet is called from a Button
in a NavigationBarItem
.
struct ContentView: View {
@State var showingSearch = false
var body: some View {
NavigationView {
VStack {
Text("Hello World")
}
.navigationBarItems(trailing:
Button(action: {
self.showingSearch.toggle()
}) {
Image(systemName: "magnifyingglass")
}
.sheet(isPresented: $showingSearch) {
SearchSheet(isPresented: self.$showingSearch)
}
)
}
}
}
class Query: ObservableObject {
@Published var input = "" {
didSet {
// Called as expected in both cases but only TextField updates the SearchSheet view.
}
}
}
struct SearchSheet: View {
@ObservedObject var query = Query()
var body: some View {
VStack {
// Does not update the SearchSheet view. I would like it understand why and how to update it.
SearchBar(text: $query.input, placeholder: "Search")
// Does update the SearchSheet view.
TextField("Search", text: $query.input)
Text("\(query.input)")
}
}
}
import SwiftUI
struct SearchBar: UIViewRepresentable {
@Binding var text: String
var placeholder: 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() -> SearchBar.Coordinator {
return Coordinator(text: $text)
}
func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {
let searchBar = UISearchBar(frame: .zero)
searchBar.delegate = context.coordinator
searchBar.placeholder = placeholder
searchBar.searchBarStyle = .minimal
searchBar.autocapitalizationType = .none
return searchBar
}
func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBar>) {
uiView.text = text
}
}
struct SearchBar_Previews: PreviewProvider {
@State private static var text = ""
static var previews: some View {
SearchBar(text: $text, placeholder: "Search")
}
}
Moving the display of the sheet out from navigationBarItems
resolves the issue. At the time I believe this is a bug.
.navigationBarItems(trailing:
Button(action: {
self.showingSearch.toggle()
}) {
Image(systemName: "magnifyingglass")
}
)
.sheet(isPresented: $showingSearch) {
SearchSheet(isPresented: self.$showingSearch)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.