如何更改导航栏中搜索栏的位置?

How to change position of SearchBar in NavigationBar?

我遵循 this article 如何在 NavigationBar 中显示 SearchBar。我这样将它集成到我的视图中:

struct ExploreView: View {

    @ObservedObject var searchBar = SearchBar()

    var body: some View {
        NavigationView {
            ZStack {
                Color(red: 250/255, green: 250/255, blue: 250/255)
                    .edgesIgnoringSafeArea(.all)
            
                VStack(spacing: 0) {
                    Image(R.image.navigationBarBackground)
                        .resizable()
                        .scaledToFit()
                        .frame(width: UIScreen.main.bounds.width)
                        .edgesIgnoringSafeArea(.all)
                    Spacer()
                }
            }
            .navigationBarTitle("", displayMode: .inline)
            .add(self.searchBar)
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

class SearchBar: NSObject, ObservableObject {

    @Published var text: String = ""
    let searchController: UISearchController = UISearchController(searchResultsController: nil)

    override init() {
        super.init()
        self.searchController.obscuresBackgroundDuringPresentation = false
        self.searchController.searchResultsUpdater = self
    }
}

extension SearchBar: UISearchResultsUpdating {

    func updateSearchResults(for searchController: UISearchController) {
        // Publish search bar text changes.
        if let searchBarText = searchController.searchBar.text {
            self.text = searchBarText
        }
    }
}

struct SearchBarModifier: ViewModifier {

    let searchBar: SearchBar

    func body(content: Content) -> some View {
        content
            .overlay(
                ViewControllerResolver { viewController in
                    viewController.navigationItem.searchController = self.searchBar.searchController
                }
                .frame(width: 0, height: 0)
            )
    }
}

extension View {
    func add(_ searchBar: SearchBar) -> some View {
        return self.modifier(SearchBarModifier(searchBar: searchBar))
    
    }
}

final class ViewControllerResolver: UIViewControllerRepresentable {

    let onResolve: (UIViewController) -> Void
    
    init(onResolve: @escaping (UIViewController) -> Void) {
        self.onResolve = onResolve
    }

    func makeUIViewController(context: Context) -> ParentResolverViewController {
        ParentResolverViewController(onResolve: onResolve)
    }

    func updateUIViewController(_ uiViewController: ParentResolverViewController, context: Context) {
    }
}

class ParentResolverViewController: UIViewController {

    let onResolve: (UIViewController) -> Void

    init(onResolve: @escaping (UIViewController) -> Void) {
        self.onResolve = onResolve
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("Use init(onResolve:) to instantiate ParentResolverViewController.")
    }
    
    override func didMove(toParent parent: UIViewController?) {
        super.didMove(toParent: parent)
    
        if let parent = parent {
            onResolve(parent)
        }
    }
}

看起来像这样:SearchBar: inactive, SearchBar: active

但我希望将非活动 SearchBar 与活动 SearchBar 放在同一位置以避免空闲 space。最后它应该看起来像 Instagram 应用程序中的 SearchBar。有人知道怎么做吗?

将这段代码添加到 SearchBarinit() 方法中。它会在激活时使搜索栏位于同一位置。

self.searchController.hidesNavigationBarDuringPresentation = false

如果您想将搜索栏设置为导航栏标题而不是文本,请在 overlay(_:)

更改此代码

ViewControllerResolver { viewController in
    viewController.navigationItem.searchController = self.searchBar.searchController
}

ViewControllerResolver { viewController in
    viewController.navigationItem.titleView = self.searchBar.searchController.searchBar
}