为啥导航栏中的 SwiftUI TextField 一次只接受输入一个字符
Posted
技术标签:
【中文标题】为啥导航栏中的 SwiftUI TextField 一次只接受输入一个字符【英文标题】:Why does a SwiftUI TextField inside a navigation bar only accept input one character at a time为什么导航栏中的 SwiftUI TextField 一次只接受输入一个字符 【发布时间】:2020-04-20 14:54:09 【问题描述】:我想让用户过滤长列表中的数据,以便更轻松地找到匹配的标题。
我在导航栏中放置了一个 TextView:
.navigationBarTitle(Text("Library"))
.navigationBarItems(trailing: TextField("search", text: $modelData.searchString)
我有一个响应搜索字符串变化的可观察对象:
class DataModel: ObservableObject
@Published var modelData: [PDFSummary]
@Published var searchString = ""
didSet
if searchString == ""
modelData = Realm.studyHallRealm.objects(PDFSummary.self).sorted(by: $0.name < $1.name )
else
modelData = Realm.studyHallRealm.objects(PDFSummary.self).sorted(by: $0.name < $1.name ).filter( $0.name.lowercased().contains(searchString.lowercased()) )
一切正常,除了我必须在输入每个字母后点击该字段。出于某种原因,输入每个字母后焦点从字段中移开(除非我点击建议的自动更正 - 整个字符串一次正确添加到字符串中)
【问题讨论】:
【参考方案1】:问题在于完全重建NavigationView
,导致文本字段焦点下降。
这是工作方法。使用 Xcode 11.4 / ios 13.4 测试
我们的想法是避免重建 NavigationView
基于 SwiftUI 引擎更新修改过的视图的知识,因此使用分解我们在本地进行修改并仅在子视图之间直接传输所需的值而不影响顶部 @987654325 @,因此最后保留的立场。
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())
【讨论】:
这正是我所需要的。当我键入并点击删除时,列表会增长和缩小。再次感谢您的帮助。以上是关于为啥导航栏中的 SwiftUI TextField 一次只接受输入一个字符的主要内容,如果未能解决你的问题,请参考以下文章
自定义属性包装器无法准确反映我在 SwiftUI 中的 TextField 的状态,知道为啥吗?