简体   繁体   English

在导航栏中显示搜索栏而不在 iOS 11 上滚动

[英]Show search bar in navigation bar without scrolling on iOS 11

I'm attaching a UISearchController to the navigationItem.searchController property of a UITableViewController on iOS 11. This works fine: I can use the nice iOS 11-style search bar.我将 UISearchController 附加到 iOS 11 上 UITableViewController 的navigationItem.searchController属性。这很好用:我可以使用漂亮的 iOS 11 样式的搜索栏。

However, I'd like to make the search bar visible on launch.但是,我想让搜索栏在启动时可见。 By default, the user has to scroll up in the table view to see the search bar.默认情况下,用户必须在表格视图中向上滚动才能看到搜索栏。 Does anyone know how is this is possible?有谁知道这怎么可能?

在此处输入图片说明 在此处输入图片说明

Left: default situation after launch.左:启动后的默认情况。 Right: search bar made visible (by scrolling up).右:搜索栏可见(通过向上滚动)。 I'd like to have the search bar visible after launch, as in the right screenshot.我想让搜索栏在启动后可见,如右图所示。

I already found that the search bar can be made visible by setting the property hidesSearchBarWhenScrolling of my navigation item to false.我已经发现可以通过将我的导航项的属性hidesSearchBarWhenScrolling设置为 false 来使搜索栏可见。 However, this causes the search bar to always be visible — even when scrolling down —, which is not what I want.但是,这会导致搜索栏始终可见 - 即使向下滚动 - 这不是我想要的。

The following makes the search bar visible at first, then allows it to hide when scrolling:以下内容首先使搜索栏可见,然后在滚动时将其隐藏:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if #available(iOS 11.0, *) {
        navigationItem.hidesSearchBarWhenScrolling = false
    }
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if #available(iOS 11.0, *) {
        navigationItem.hidesSearchBarWhenScrolling = true
    }
}

Using isActive didn't do what I wanted, it makes the search bar active (showing cancel button, etc.), when all I want is for it to be visible.使用isActive并没有做我想要的,它使搜索栏处于活动状态(显示取消按钮等),而我想要的只是让它可见。

You can set the property isActive to true after adding the searchController to the navigationItem .将 searchController 添加到navigationItem后,您可以将属性isActive设置为true

Just like this:就像这样:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    searchController.isActive = true
}

For me it worked after adding following lines in viewDidLoad() method:对我来说,它在viewDidLoad()方法中添加以下行后起作用:

navigationController?.navigationBar.prefersLargeTitles = true
navigationController!.navigationBar.sizeToFit()

On iOS 13, @Jordan Wood's answer didn't work.在 iOS 13 上,@Jordan Wood 的回答无效。 Instead I did:相反,我做了:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    UIView.performWithoutAnimation {
        searchController.isActive = true
        searchController.isActive = false
    }
}

The following make searchBar to become first responder: 以下使searchBar成为第一响应者:

   override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        DispatchQueue.main.async {
            self.searchController.searchBar.becomeFirstResponder()
        }
    }
For (iOS 13.0, *) and SwiftUI

navigationController?.navigationBar.sizeToFit() navigationController?.navigationBar.sizeToFit()

Example:

struct SearchBarModifier: ViewModifier {
        let searchBar: SearchBar
        func body(content: Content) -> some View {
        content
            .overlay(
                ViewControllerResolver { viewController in
                    viewController.navigationItem.searchController = self.searchBar.searchController
                    viewController.navigationController?.navigationBar.sizeToFit()

                }
                .frame(width: 0, height: 0)
            )
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM