由于 tvOS 14.x 中没有本机搜索栏,我必须将控件包装在 UIViewControllerRepresentable 中。只要我在模拟器上测试时使用 Mac 键盘,控件就会显示甚至返回搜索结果。我的问题是屏幕键盘永远不会获得焦点。
有什么建议么?
这是 UIViewControllerRepresentable 实现。
struct ScreenerSearchBar: UIViewControllerRepresentable {
@Binding var text: String
@EnvironmentObject var searchResults : Search
typealias UIViewControllerType = UISearchContainerViewController
typealias Context = UIViewControllerRepresentableContext<ScreenerSearchBar>
func makeUIViewController(context: Context) -> UIViewControllerType {
let controller = UISearchController(searchResultsController: context.coordinator)
controller.searchResultsUpdater = context.coordinator
controller.searchBar.placeholder = "Search"
controller.searchBar.tintColor = .white
controller.inputView?.tintColor = .white
controller.searchBar.barTintColor = .white
controller.searchBar.searchBarStyle = .minimal
controller.searchBar.keyboardAppearance = .dark
return UISearchContainerViewController(searchController: controller)
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
func makeCoordinator() -> ScreenerSearchBar.Coordinator {
return Coordinator(text: $text, searchResults: searchResults)
}
//=======================================================================
class Coordinator: UIViewController, UISearchResultsUpdating {
@Binding var text: String
var searchResults : Search
init(text: Binding<String>, searchResults: Search) {
_text = text
self.searchResults = searchResults
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text else { return }
text = searchText
searchResults.search(for: text)
}
}
//=======================================================================
}
在我看来,这是我使用它的方式:
struct SearchView: View {
@EnvironmentObject var searchResults : Search
@State private var keyword = ""
let columns = [
GridItem(.fixed(400)),
GridItem(.fixed(400)),
GridItem(.fixed(400)),
GridItem(.fixed(400))
]
var body: some View {
VStack {
ScreenerSearchBar(text: $keyword)
.focusable()
HStack {
if !keyword.isEmpty {
Text("Search results for: \"\(keyword)\"")
.font(.caption)
Spacer()
}
}
.padding(.top, -150)
.focusable()
ScrollView(.vertical) {
LazyVGrid(columns: columns) {
ForEach(searchResults.screeners, id: \.id) { screener in
NavigationLink(destination: TitleDetailView(screener: screener, titleDetails: TitleDetails(), hierarchy: Hierarchy())) {
ScreenerView(screener: screener, categoryId: -99, origin: .search)
.focusable()
}
.buttonStyle(PlainNavigationLinkButtonStyle())
}
} //vgrid
.focusable()
.padding(.top, -100)
} // scrollview
} // vstack
}
}