是否有人有有效的 Swiftui 代码,可以在导航栏中生成与后退按钮内联的搜索栏?就像它是一个工具栏项一样。
目前,我有代码可以在导航后退按钮下方生成一个搜索栏,但希望它像附图所示那样排列(“hi”所在的位置):
我正在使用在示例中找到的代码:
var body: some View {
let shopList = genShopList(receiptList: allReceipts)
VStack{
}
.navigationBarSearch(self.$searchInput)
}
public extension View {
public func navigationBarSearch(_ searchText: Binding<String>) -> some View {
return overlay(SearchBar(text: searchText)
.frame(width: 0, height: 0))
}
}
fileprivate struct SearchBar: UIViewControllerRepresentable {
@Binding
var text: String
init(text: Binding<String>) {
self._text = text
}
func makeUIViewController(context: Context) -> SearchBarWrapperController {
return SearchBarWrapperController()
}
func updateUIViewController(_ controller: SearchBarWrapperController, context: Context) {
controller.searchController = context.coordinator.searchController
}
func makeCoordinator() -> Coordinator {
return Coordinator(text: $text)
}
class Coordinator: NSObject, UISearchResultsUpdating {
@Binding
var text: String
let searchController: UISearchController
private var subscription: AnyCancellable?
init(text: Binding<String>) {
self._text = text
self.searchController = UISearchController(searchResultsController: nil)
super.init()
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = true
searchController.obscuresBackgroundDuringPresentation = false
self.searchController.searchBar.text = self.text
self.subscription = self.text.publisher.sink { _ in
self.searchController.searchBar.text = self.text
}
}
deinit {
self.subscription?.cancel()
}
func updateSearchResults(for searchController: UISearchController) {
guard let text = searchController.searchBar.text else { return }
self.text = text
}
}
class SearchBarWrapperController: UIViewController {
var searchController: UISearchController? {
didSet {
self.parent?.navigationItem.searchController = searchController
}
}
override func viewWillAppear(_ animated: Bool) {
self.parent?.navigationItem.searchController = searchController
}
override func viewDidAppear(_ animated: Bool) {
self.parent?.navigationItem.searchController = searchController
}
}
}
如果有人能解决这个问题,我们将不胜感激!我知道他们在 IoS 15 中推出了 .searchable,但正在寻找也适用于早期版本的东西。
最佳答案
您可以使用.toolbar
将任何控件放在您想要的位置。修改器 (iOS 14+) 和带有 .principal
的项目放置,例如:
var body: some View {
VStack {
// rest of view
}
.toolbar {
ToolbarItem(placement: .principal) {
MySearchField(text: $searchText)
}
}
}
需要注意的几点:
主要位置会覆盖内联导航标题,无论是使用
.navigationBarTitleDisplayMode(.inline)
设置时还是如此。或者当您有一个大标题并向上滚动页面时。您的自定义 View 可能会水平扩展太多,导致后退按钮丢失任何文本组件。在这里,我使用了
TextField
来说明这一点:
您可以通过使用 .frame(maxWidth:)
指定最大宽度来缓解这种情况。 ,但至少这是需要注意的。
关于SwiftUI 搜索栏与导航栏一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68802052/