I am creating an iOS 7 app in which I'd like to have a SearchBar right bellow the NavigationBar, and I wanted them both to look like a single piece. Therefore I need to tint them with the same color (done already) and remove that hairline at the bottom of the NavigationBar and at the top of the SearchBar. How can I achieve that?
-
http://stackoverflow.com/a/21302744/1463604 – Nishant Jan 23 '14 at 08:14
5 Answers
Officially, this is only possible by setting the shadowImage
of the navigationBar to an empty image. However, a closer look at the documentation, it is said:
For a custom shadow image to be shown, a custom background image must also be set with the setBackgroundImage:forBarMetrics: method. If the default background image is used, then the default shadow image will be used regardless of the value of this property.
By using a custom background image, you would lose the blurred background translucency.
If you feel adventurous, the "hairline" is a UIImageView that is a subview of the navigation bar. You can find it and set it as hidden. This is what Apple does in their native calendar app, for example. Remember to show it when the current view disappears.

- 56,823
- 9
- 150
- 195
-
I am going to use a background image, but the NavigationBar will be opaque, so the loss of the blur effect won't affect me in this case. Another question, then, is: how can I know which subview to hide, since it contains more than one UIImageView? – Guilherme Sep 26 '13 at 21:01
-
If you are using a custom background image, you should not touch the view hierarchy. You can use an empty `shadowImage`. I think I hid all image views in my case. – Léo Natan Sep 26 '13 at 21:04
-
I couldn't make it work. I tried setting the shadowImage as an transparent 1x1 png file, the same file colored with the same color as the NavigationBar, with `[UIImage new]`, and even `nil`, but none of them worked. – Guilherme Sep 26 '13 at 21:11
-
Try doing in the appearance methods. When your app loads, but before your view controller is loaded, `[[UINavigationBar appearance] setShadowImage:[UIImage new]];` – Léo Natan Sep 26 '13 at 21:15
-
Nope. I added that to the AppDelegate `application:didFinishLaunchingWithOptions:`, but the hairline is still there. – Guilherme Sep 26 '13 at 21:19
-
If your app starts directly from a storyboard, the view controller is loaded before `application:didFinishLaunchingWithOptions:`. – Léo Natan Sep 26 '13 at 21:31
-
But the ViewController in which the NavigationBar is contained is not the first ViewController to be loaded. The first is a TabBarController, and its child ViewControllers have NavigationBars. Does it make it somewhat easier? – Guilherme Sep 26 '13 at 21:39
-
Put a breakpoint in the `initWithCoder:` method (called when using nibs) and see which is called first. In our app, this worked, but I did not like the custom background image option. – Léo Natan Sep 26 '13 at 21:43
-
That actually did work! Thanks a lot. Any idea on how to do the same thing with the SearchBar's top hairline? – Guilherme Sep 30 '13 at 13:08
-
2I was able to remove the searchBar simply by using a background image. – Guilherme Sep 30 '13 at 19:45
use following code in AppDelegate (didFinishLaunchingWithOptions)
Swift :
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
Objective c :
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init]
forBarPosition:UIBarPositionAny
barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];

- 1,924
- 21
- 31
-
1For Swift 4 ... Please update the code to the following UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .any, barMetrics: .default) UINavigationBar.appearance().shadowImage = UIImage() – Mohamed Saleh Jan 09 '19 at 16:53
-
1
Swift 3:
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")

- 723
- 6
- 17
-
Why do we have to set a string as parameter??, that doesn't make sense, could be much better set an enum. – LeoGalante Feb 13 '17 at 19:42
-
2Searched and tried a lot of different solution. This was the only one that worked with a UISearchController. – jfredsilva Sep 28 '17 at 08:53
-
Objective-C: [self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"]; – jfredsilva Sep 28 '17 at 09:17
One way to remove the hairline on the top and bottom of a UISearchBar is to replace the background image with a stretchable one, that does not have that thin border. Simply make a square shaped png with the color of your choice, then:
[searchBar setBackgroundImage:[[UIImage imageNamed:@"SearchBarImage"] resizableImageWithCapInsets:UIEdgeInsetsMake( 10, 10, 10, 10)]];
Since the background is solid you can use pretty much whatever values you want for the insets.

- 41
- 2
-
To avoid an appearance bug that occurs in transition to the search, I set the insets to 0,0,0,0. It still worked great and I didn't experience the graphics corruption upon tapping the search field. – Jordan H Oct 30 '14 at 20:16
For those who interested how to implement "adventurous" approach of @Leo Natan, I added the sample code in my answer to the similar question.

- 1
- 1

- 12,424
- 2
- 27
- 26