swift - SwiftUI UISearchController searchResultsController 导航堆栈问题
问题描述
我UIViewControllerRepresentable
有为 SwiftUI 制作的 UISearchController,如下所示:
struct SearchViewController<Content: View>: UIViewControllerRepresentable {
var content: () -> Content
let searchResultsView = SearchResultsView()
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func makeUIViewController(context: Context) -> UINavigationController {
let rootViewController = UIHostingController(rootView: content())
let navigationController = UINavigationController(rootViewController: rootViewController)
let searchResultsController = UIHostingController(rootView: searchResultsView)
// Set nav properties
navigationController.navigationBar.prefersLargeTitles = true
navigationController.definesPresentationContext = true
// Create search controller
let searchController = UISearchController(searchResultsController: searchResultsController)
searchController.searchBar.autocapitalizationType = .none
searchController.delegate = context.coordinator
searchController.searchBar.delegate = context.coordinator // Monitor when the search button is tapped.
// Create default view
rootViewController.navigationItem.searchController = searchController
rootViewController.title = "Search"
return navigationController
}
func updateUIViewController(_ navigationController: UINavigationController, context: UIViewControllerRepresentableContext<SearchViewController>) {
//
}
}
这有效,并searchResultsController
在用户搜索时显示。但是,searchResultsController
似乎不知道它是导航上下文/堆栈,因此我无法从searchResultsController
.
是否可以将其结构化以允许从 导航searchResultsController
,或者这是当前 SwiftUI 的限制。
非常感谢任何建议!
解决方案
我最近还需要在我的应用程序中实现此功能(搜索栏,如导航栏)。看着你的片段真的启发了 m2!我先谢谢了!
在向你ula1990、Lorenzo Boaro和V8tr学习之后,我实现了自己的。
我将其设置searchResultsController
为nil
(由于其中的导航链接不可点击,因此我将其设置为 nil)。
代码:
struct SearchController<Result: View>: UIViewControllerRepresentable {
@Binding var searchText: String
private var content: (_ searchText:String)->Result
private var searchBarPlaceholder: String
init(_ searchBarPlaceholder: String = "", searchedText: Binding<String>,
resultView: @escaping (_ searchText:String) -> Result) {
self.content = resultView
self._searchText = searchedText
self.searchBarPlaceholder = searchBarPlaceholder
}
func makeUIViewController(context: Context) -> UINavigationController {
let contentViewController = UIHostingController(rootView: SearchResultView(result: $searchText, content: content))
let navigationController = UINavigationController(rootViewController: contentViewController)
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = context.coordinator
searchController.obscuresBackgroundDuringPresentation = false // for results
searchController.searchBar.placeholder = searchBarPlaceholder
contentViewController.title = "\\(Title)" // for customization
contentViewController.navigationItem.searchController = searchController
contentViewController.navigationItem.hidesSearchBarWhenScrolling = true
contentViewController.definesPresentationContext = true
searchController.searchBar.delegate = context.coordinator
return navigationController
}
func updateUIViewController(_ uiViewController: UINavigationController, context: UIViewControllerRepresentableContext<SearchController>) {
//
}
}
extension SearchController {
func makeCoordinator() -> SearchController<Result>.Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UISearchResultsUpdating, UISearchBarDelegate {
var parent: SearchController
init(_ parent: SearchController){self.parent = parent}
// MARK: - UISearchResultsUpdating
func updateSearchResults(for searchController: UISearchController) {
self.parent.searchText = searchController.searchBar.text!
}
// MARK: - UISearchBarDelegate
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
self.parent.searchText = ""
}
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
self.parent.searchText = ""
return true
}
}
}
// "nofity" the result content about the searchText
struct SearchResultView<Content: View>: View {
@Binding var searchText: String
private var content: (_ searchText:String)->Content
init(result searchText: Binding<String>, @ViewBuilder content: @escaping (_ searchText:String) -> Content) {
self._searchText = searchText
self.content = content
}
var body: some View {
content(searchText)
}
}
如果这是您想要的,我不知道,但再次感谢!
推荐阅读
- java - MIP SDK Java Wrapper 示例无法启动
- python - Jupyter 以编程方式执行热键
- javascript - 触发更新功能时数据被复制 - Firebase
- azure - 使用 Python 的 Azure 服务总线
- google-cloud-platform - GCP 上带有“resource.sourceMachineImage”的新 VM 错误消息
- excel - 如何遍历一系列 10 个电子邮件地址并将它们添加到 VBA 中的电子邮件?
- ruby-on-rails - Rails 使用 micropost 脚手架时不呈现错误页面
- python-3.x - 将列表中的数据添加到已有数据的 csv 列
- angular - Angular 将数据从一个组件传递到另一个小部件组件
- c - 对 char* 数组 c99 使用拆分声明是否兼容?