简体   繁体   中英

iOS 9 searchBar disappears from table header view when UISearchController is active

The structure:

View1 (click a button) -> present modally (MyModalView: UITableViewController)

MyModalView has UISearchController embedded. The searchBar of UISearchController is placed in MyModalView.tableView.tableHeaderView.

It's been working fine since iOS 8.0. However on iOS 9, the searchBar disappear when the UISearchController is active. Please take a look at theses pictures below

The modal view: 模态视图

UISearchController active on iOS 8: iOS 8中的搜索栏

UISearchController active on iOS 9: iOS 9中的搜索栏

The very standard code:

override func viewDidLoad() {
    super.viewDidLoad()

    // Dynamically create a search controller using anonymous function
    self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false

        controller.searchBar.sizeToFit()
        controller.searchBar.delegate = self

        self.tableView.tableHeaderView = controller.searchBar

        return controller
    })()

    // Auto sizing row & cell height
    self.tableView.estimatedRowHeight = 130
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.definesPresentationContext = true

    // No footer for better presentation
    self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}

This issue also happens in iOS 9.1 beta...

Any idea / pointer would be deeply appreciated

Cheers.

I'm not sure what exactly is the problem but I 'fixed' it by:

self.searchController.hidesNavigationBarDuringPresentation = NO;
self.definesPresentationContext = NO;

My guess is that UISearchController is doing something funky when it is trying to present as a navigation bar. So, this is a hack but it at least doesn't block the user. The search bar doesn't do the cool animation and cover up the navigation bar.

It seems all of us got the same problem but they were solved in different ways. However none of the suggested answers worked for me :(. Nevertheless thank you all for your time.

I got a solution that solved my problem. It is setting Extend Edges - Under Opaque Bars of my (MyModalView: UITableViewController) to true in the Storyboard using Interface Builder.

In summary:

MyModalView: UITableViewController, in Storyboard using Interface Builder has

Extend Edges: - Under Top Bars ticked - Under Bottom Bars ticked - Under Opaque Bars ticked

截图

I found it's the simulated metrics (top bar) in storyboard that's cause this problem. In my case, the following lines work, but I still don't know why.

- (void)willPresentSearchController:(UISearchController *)searchController {
    // do something before the search controller is presented
    self.navigationController.navigationBar.translucent = YES;
}

-(void)willDismissSearchController:(UISearchController *)searchController
{
    self.navigationController.navigationBar.translucent = NO;
}

I had to

self.aNavigationController?.extendedLayoutIncludesOpaqueBars = true

I found a similar question here but in my case it was not on the viewDidLoad method. I had to try different views until it worked. Now I can have both a custom navigation bar color and the search bar,

Thanks @wiles duan and @Techprimate

In my case, I fixed this issue by setting:

self.definesPresentationContext = NO;

And implement the following 2 methods in UISearchControllerDelegate

- (void)willPresentSearchController:(UISearchController *)searchController {
    // do something before the search controller is presented
    self.navigationController.navigationBar.translucent = YES;
}

-(void)willDismissSearchController:(UISearchController *)searchController
{
    self.navigationController.navigationBar.translucent = NO;
}

I fixed it in my case by removing

definesPresentationContext = true

I didn't test yet if there are any disadvantages of removing this!

I don't have a navigation bar in this place of an app. None of other SO posts helped me, so I've fixed it this way:

- (void)layoutSubviews
{
    [[[self searchController] searchBar] sizeToFit];
}

I had the same problem, and when I debugged the UI on Xcode I found that the UISearchBar view was moved to another view and the width was zeroed.

I fixed it by setting definesPresentationContext property of the UISearchController to false , and setting it true for the containing UITableViewController .

I added only one line to your viewDidLoad() .

override func viewDidLoad() {
    super.viewDidLoad()

    // Dynamically create a search controller using anonymous function
    self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false
        controller.definesPresentationContext = false    // Disable the presentation controller

        controller.searchBar.sizeToFit()
        controller.searchBar.delegate = self

        self.tableView.tableHeaderView = controller.searchBar

        return controller
    })()

    // Auto sizing row & cell height
    self.tableView.estimatedRowHeight = 130
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.definesPresentationContext = true    // This one remains the same

    // No footer for better presentation
    self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}

在故事板中将navigationBar永久设置为半透明解决了我的问题。

It works

override func viewDidLoad() {
    super.viewDidLoad()

    self.extendedLayoutIncludesOpaqueBars = !self.navigationController!.navigationBar.translucent
}

如果要隐藏导航栏,并在全屏显示搜索控制器,请在导航栏上设置以下内容,搜索栏不会消失:

navigationController?.navigationBar.translucent = true
sc.hidesNavigationBarDuringPresentation = false

does the trick for me

lazy var searchController:UISearchController = {
        let sc = UISearchController(searchResultsController: nil)
        sc.searchResultsUpdater = self
        sc.obscuresBackgroundDuringPresentation = false
        sc.searchBar.placeholder = "Search"
        sc.hidesNavigationBarDuringPresentation = false
        return sc
    }()

None of them worked for me, I fixed it using this hack

func position(for bar: UIBarPositioning) -> UIBarPosition {
    if UIDevice.current.userInterfaceIdiom == .pad {
        return .top
    } else {
        if iOSVersion <= 9 {
            return .top
        }
        return .topAttached
    }


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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