fzwo
fzwo

Reputation: 9902

Remove UIToolbar hairline in iOS 7

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.

Upvotes: 29

Views: 13965

Answers (10)

ober
ober

Reputation: 2481

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 
}

Upvotes: 0

Dmitri Pavlutin
Dmitri Pavlutin

Reputation: 19080

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.

Upvotes: 4

abc123
abc123

Reputation: 8303

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];

Upvotes: 0

dbart
dbart

Reputation: 5566

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.

Upvotes: 1

Aqib Mumtaz
Aqib Mumtaz

Reputation: 5064

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

Upvotes: 2

iCanCode
iCanCode

Reputation: 1011

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];

Upvotes: 1

Nishant
Nishant

Reputation: 12617

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

[self.navigationController.navigationBar setShadowImage:[UIImage new]];

Upvotes: 1

cire.boroguies
cire.boroguies

Reputation: 1071

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.

Upvotes: 84

Thyraz
Thyraz

Reputation: 2432

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.

Upvotes: 5

tinrocket
tinrocket

Reputation: 144

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;
            }
        }

Upvotes: 5

Related Questions