Проблема в перестроении NavigationView
полностью, что приводит к упадению фокуса текстового поля.
Вот рабочий подход. Протестировано с Xcode 11.4 / iOS 13.4
Идея состоит в том, чтобы избежать перестроения NavigationView
, основываясь на знании того, что движок SwiftUI обновляет только измененных представлений, поэтому, используя декомпозицию, мы вносим изменения локально и переносим желаемые значения только между подпредставлениями, напрямую не влияющими на верх NavigationView
, в результате чего последний сохраненный стенд.
class QueryModel: ObservableObject {
@Published var query: String = ""
}
struct ContentView: View {
// No QueryModel environment object here -
// implicitly passed down. !!! MUST !!!
var body: some View {
NavigationView {
ResultsView()
.navigationBarTitle(Text("Library"))
.navigationBarItems(trailing: SearchItem())
}
}
}
struct ResultsView: View {
@EnvironmentObject var qm: QueryModel // << injected here from top
var body: some View {
VStack {
Text("Search: \(qm.query)") // receive query string
}
}
}
struct SearchItem: View {
@EnvironmentObject var qm: QueryModel // << injected here from top
@State private var query = "" // updates only local view
var body: some View {
let text = Binding(get: { self.query }, set: {
self.query = $0; self.qm.query = $0; // transfer query string
})
return TextField("search", text: text)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(QueryModel())
}
}