29

In iOS 7, Apple has changed UIToolbar to display a 1px hairline at its top. This is visually distracting in some cases, and there does not seem to be any public API to remove it.

Setting a shadowImage does not work.

I am looking for a way of removing the hairline in a relatively clean way, and keep the ordinary background blur.

Jano
  • 62,815
  • 21
  • 164
  • 192
fzwo
  • 9,842
  • 3
  • 37
  • 57

10 Answers10

84

If you set youBar.clipsToBounds = YES, the hairline disappear.

Hope this help.

[EDIT]

For the navigationBar bottom hairline, the solution here https://stackoverflow.com/a/18180330/2011578 also works great.

Community
  • 1
  • 1
cire.boroguies
  • 1,071
  • 9
  • 18
  • Ah, good idea. I also noticed, that the shadow image is below the nav-bar – Thyraz Oct 15 '13 at 10:06
  • Combining with `.barStyle = -1` allows for a completely invisible toolbar (IAS HIG uncertain however) –  Jul 28 '15 at 23:42
5

The hairline border is a UIImageView subview of the toolbar, you can hide it like this:

        for (UIView *subView in [self.toolbar subviews]) {
            if ([subView isKindOfClass:[UIImageView class]]) {
                // Hide the hairline border
                subView.hidden = YES;
            }
        }
tinrocket
  • 144
  • 3
  • 2
    It's always a bad idea to make assumptions about internal implementation details like this. Apple could change the implementation at any time. – Greg Brown Jan 30 '17 at 20:17
5

The line is it's shadowImage. It can simply be removed by applying an empty UIImage. According to the documentation you also have to set a custom background image:

- (void)viewDidLoad {
  [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
  self.navigationController.navigationBar.shadowImage = [[UIImage alloc ]init];
}

Be aware: Translucency won't work if you set own images in case you need that.

Thyraz
  • 2,412
  • 2
  • 21
  • 23
  • I think I should clarify my question then. I need to remove the hairline, but keep the blur (so no setting the background image). – fzwo Oct 14 '13 at 10:53
  • 1
    This used to work in iOS 6, but in iOS 7, setting the shadow image to a transparent image will not work — there is a very faint, bright mark where the shadow is drawn. – tinrocket Oct 15 '13 at 02:12
4

When using Storyboards,

self.clipsToBounds = true

can be setup for the Toolbar in the Runtime attributes. This will hide the hairline. Verified in iOS 7 and 8.

Dmitri Pavlutin
  • 18,122
  • 8
  • 37
  • 41
2

It can be resolved easily on storyboard:

Select the View which is added as UIBarButtonItem Container & set its "Clip Subviews" & Run app.

enter image description here

Aqib Mumtaz
  • 4,936
  • 1
  • 36
  • 33
1

this solution worked for me... tried this for iOS 7

[self.navigationController.navigationBar setShadowImage:[UIImage new]];
Nishant
  • 12,529
  • 9
  • 59
  • 94
1

Not exactly what you want but surely this answer will help someone.

If you want to change the bottom-border(shadow) color of UINavigationBar or UIToolbar instead of hiding it, you should set the background image and shadow image to your bar.

For changing the the UINavigationBar's bottom-border(shadow)

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"yourImageName"] forBarMetrics:UIBarMetricsDefault]; [self.navigationController.navigationBar setShadowImage:[UIImage imageNamed:@"yourImageName"]];

For changing the the UIToolbar's bottom-border(shadow)

[yourToolBar setBackgroundImage:[UIImage imageNamed:@"yourImageName"] forToolbarPosition:UIBarPositionBottom barMetrics:UIBarMetricsDefault];

[yourToolBar setShadowImage:[UIImage imageNamed:@"yourImageName"] forToolbarPosition:UIBarPositionBottom];

iCanCode
  • 1,001
  • 1
  • 13
  • 24
1

While somewhat hacky, subclassing UITabBar and overriding the - (void)addSubview: method, we can prevent the hairline separator from being added to the view hierarchy altogether:

- (void)addSubview:(UIView *)view {
    if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height < 2.0f) {
        return;
    }
    [super addSubview:view]; 
}

This way we'll get both the blurred tab bar and remove the hairline separator. It also ensures that UITabBar won't clip views to bounds, which is important for effects like large center buttons or other UI components.

dbart
  • 5,468
  • 2
  • 23
  • 19
0

I could not get this working via Storyboard in my case. I eventually used the appearance proxy to eliminate the shadow on all of my tool bars:

[[UIToolbar appearance] setClipsToBounds:YES];

abc123
  • 8,043
  • 7
  • 49
  • 80
0

If you need hide hairline and show shadow clipsTobounds don't help

use:

TOOLBAR.subviews
      .filter { $0 is UIImageView }
      .forEach { $0.hidden = true }

or:

for case let imageView is UIImageView in TOOLBAR.subviews {
    imageView.hidden = true 
}
ober
  • 2,363
  • 1
  • 19
  • 17