SwiftUI、tvOS、UIViewControllerRepresentable 和焦点问题
SwiftUI, tvOS, UIViewControllerRepresentable and a focus issue
我正在尝试在 tvOS SwiftUI 应用程序中实现搜索功能。我使用 UISearchController
作为最直接的解决方案来做到这一点。我已经将它包裹在符合 UIViewControllerRepresentable
的 SearchView
中。问题是,看起来焦点引擎拒绝关注视图控制器的一部分 UI - UISearchBar
被包装。我可以在模拟器中从我的 Mac 中输入搜索查询,以验证搜索是否有效,但当然,这不是真实的。
我尝试将 .focusable()
修饰符添加到 SearchView
中,但没有帮助。
还尝试在 UISearchController
和 UISearchContainerViewController
的自定义子类中实现 shouldUpdateFocus
、preferredFocusEnvironments
和 didUpdateFocus
回调,但根本没有调用这些回调.
我想我在这里遗漏了一些非常简单的东西。
这是 SearchView
:
的代码
struct SearchView: UIViewControllerRepresentable {
@Binding var text: String
typealias UIViewControllerType = UISearchContainerViewController
typealias Context = UIViewControllerRepresentableContext<SearchView>
func makeUIViewController(context: Context) -> UIViewControllerType {
let controller = UISearchController(searchResultsController: context.coordinator)
controller.searchResultsUpdater = context.coordinator
return UISearchContainerViewController(searchController: controller)
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
func makeCoordinator() -> SearchView.Coordinator {
return Coordinator(text: $text)
}
class Coordinator: UIViewController, UISearchResultsUpdating {
@Binding var text: String
init(text: Binding<String>) {
_text = text
super.init(nibName: nil, bundle: nil)
}
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text else { return }
text = searchText
}
}
}
还有主要的ContentView
(我去掉了一些不重要的代码):
struct ContentView: View {
@State var model = ["aa", "ab", "bb", "bc", "cc", "dd", "ee"]
@State var searchQuery: String = ""
var body: some View {
SearchView(text: $searchQuery)
List {
ForEach(model.filter({ [=11=].hasPrefix(searchQuery) })) { item in
Text(item)
}
}
}
}
最后,可以通过 .searchable
修饰符完成,在 iOS 15 beta 1 中引入,不再需要 UISearchController
包装器。
P.S。得到 Apple 对这个错误的官方回应 (FB8974300) 也使用 .searchable
修饰符,所以旧版本没有修复。
我正在尝试在 tvOS SwiftUI 应用程序中实现搜索功能。我使用 UISearchController
作为最直接的解决方案来做到这一点。我已经将它包裹在符合 UIViewControllerRepresentable
的 SearchView
中。问题是,看起来焦点引擎拒绝关注视图控制器的一部分 UI - UISearchBar
被包装。我可以在模拟器中从我的 Mac 中输入搜索查询,以验证搜索是否有效,但当然,这不是真实的。
我尝试将 .focusable()
修饰符添加到 SearchView
中,但没有帮助。
还尝试在 UISearchController
和 UISearchContainerViewController
的自定义子类中实现 shouldUpdateFocus
、preferredFocusEnvironments
和 didUpdateFocus
回调,但根本没有调用这些回调.
我想我在这里遗漏了一些非常简单的东西。
这是 SearchView
:
struct SearchView: UIViewControllerRepresentable {
@Binding var text: String
typealias UIViewControllerType = UISearchContainerViewController
typealias Context = UIViewControllerRepresentableContext<SearchView>
func makeUIViewController(context: Context) -> UIViewControllerType {
let controller = UISearchController(searchResultsController: context.coordinator)
controller.searchResultsUpdater = context.coordinator
return UISearchContainerViewController(searchController: controller)
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
func makeCoordinator() -> SearchView.Coordinator {
return Coordinator(text: $text)
}
class Coordinator: UIViewController, UISearchResultsUpdating {
@Binding var text: String
init(text: Binding<String>) {
_text = text
super.init(nibName: nil, bundle: nil)
}
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text else { return }
text = searchText
}
}
}
还有主要的ContentView
(我去掉了一些不重要的代码):
struct ContentView: View {
@State var model = ["aa", "ab", "bb", "bc", "cc", "dd", "ee"]
@State var searchQuery: String = ""
var body: some View {
SearchView(text: $searchQuery)
List {
ForEach(model.filter({ [=11=].hasPrefix(searchQuery) })) { item in
Text(item)
}
}
}
}
最后,可以通过 .searchable
修饰符完成,在 iOS 15 beta 1 中引入,不再需要 UISearchController
包装器。
P.S。得到 Apple 对这个错误的官方回应 (FB8974300) 也使用 .searchable
修饰符,所以旧版本没有修复。