UISearchController doesn't work properly with a non-translucent UINavigationBar
Asked Answered
M

5

24

Currently I am trying to embed a UISearchController into my application. But the UISearchBar, which is a property of the UISearchController, doesn't get displayed properly, if the UINavigationBar is non-translucent. Usually after tapping the UISearchBar property, the UINavigationBar moves up to make room for the UISearchBar. You can see the result on the following screenshot:

https://www.dropbox.com/s/172k63zr2bhj84t/Normal_behaviour.png?dl=0

But if the "translucent" property of the UINavigationBar is set to "NO", the UISearchBar doesn't get displayed properly, because the background of the status bar remains transparent, as you can see on the following screenshot:

https://www.dropbox.com/s/v5cnxoj9ms6976r/Wrong_behaviour.png?dl=0

To demonstrate this weird behaviour, I have modified the sample project provided by Apple:

https://developer.apple.com/library/ios/samplecode/TableSearch_UISearchController/Introduction/Intro.html

Here you can download the modified version:

https://www.dropbox.com/s/7icfe6kap98g1e8/TableSearchwithUISearchControllerObj-CandSwift_MODIFIED.zip?dl=0

The modification is in file "APLMainTableViewController.m" line 33.

Mayes answered 14/10, 2014 at 19:56 Comment(2)
Yeah, I'm seeing this too. Very frustrating.Phlegethon
Screenshots don't exist. Could you please upload them again?Xantho
Z
28

It's clearly a bug (rdar://20942583).

My workaround is to set

self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;

This allows you to keep the navigation bar opaque. The downside is that the content flows below the bar even if it can't be seen, creating some overhead.

Ziguard answered 13/5, 2015 at 21:56 Comment(5)
The edgesForExtendedLayout adjustment wasn't necessary for me. But this worked.Tattered
This worked for me too. I've been wrecking head over this one for the past two days. It did however required the two lines.Illuminate
those two lines are required on the target vc?Lenity
@Lenity no, on the presenting VC.Ziguard
WHY Apple WHY!? You stole 3 hours of my life with this, I want them back!Vue
P
13

All I needed was:

func viewDidLoad() { 

    extendedLayoutIncludesOpaqueBars = true
}
Purveyance answered 7/7, 2015 at 15:39 Comment(0)
B
6

One workaround for this is to make the status bar translucent just before the search is going to become active, and remove the translucency when the search is about become inactive.

You can do this by registering your view controller as a delegate of UISearchController, and implementing the willPresentSearchController and willDismissSearchController methods. For example (in Swift):

Declare your view controller as a delegate of UISearchController:

 class MyViewController: UITableViewController, UISearchControllerDelegate

Don't forget to actually set it as the delegate, for instance in viewDidLoad add:

    searchController.delegate = self

And finally:

func willPresentSearchController(searchController: UISearchController) {
    navigationController?.navigationBar.translucent = true
}

func willDismissSearchController(searchController: UISearchController) {
    navigationController?.navigationBar.translucent = false
}
Bemuse answered 29/4, 2015 at 13:55 Comment(2)
This worked for me. Why does Apple even support changing the barTintColor on nav bars?Ulmer
Had a headache a couple days. Thank you man, saved my life. Need to set it back to false when pushing new view controller and also set it to searchController.isActive on viewDidAppear.Ranit
P
0

Ok, this one is a SUPER pain to debug but not that bad to fix. It's all down to the way Apple changed the appearance of navigation bars. It can be fixed by creating a UINavigationBarAppearance object, configuring it with the visual properties you want (i.e. background colour etc) and then assigning it to standardAppearance and scrollEdgeAppearance on UINavigationBar.appearance() - you can have two different instances with different settings if you want.

A simple implementation might look like this:

let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = barColor
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: textColor]

UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance

(Naturally replace barColor and textColor with the colours of your choice!)

Platinous answered 9/12, 2020 at 10:28 Comment(0)
D
-1

if someone have a problem like non-translucent hidden the search bar u can just had this :

self.definesPresentationContext = true

Regards

Dinnerware answered 8/8, 2016 at 15:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.