How do I disable the navigation bar shadow in iOS

2019-01-21 04:03发布

问题:

It seems in iOS 6, a drop shadow is automatically added to the navigation bar even when you set a custom background image. I'm pretty sure this wasn't the case with iOS 5 as when I test the same code in the iOS 5 and 6 sim, the shadow appears in iOS 6 but not 5.

Does anyone know anything about this? Or how to enable/disable it?

回答1:

Place this in your AppDelegate

[[UINavigationBar appearance] setShadowImage:[UIImage new]];
// is IOS 7 and later
[[UINavigationBar appearance] setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];

This is what did it for me. Hope it helps!

Swift version with updates from comments

    UINavigationBar.appearance().shadowImage = UIImage()
    UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: .Default)


回答2:

I know this has been solved with more complicated answers above, but this is the quickest and easiest way I hid the shadow under the navigation bar.

self.navigationController.navigationBar.clipsToBounds = YES;


回答3:

Note from the Apple dev docs on the subject of the shadowImage property:

Discussion: The default value is nil, which corresponds to the default shadow image. When non-nil, this property represents a custom shadow image to show instead of the default. 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.

So to use the nil UIImage hack you must also be setting a custom nav bar background image. This can be a nil image too, which results in a nice flat, clean 'metro' style nav bar :

[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
        [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];


回答4:

Also you can try this:

controller.navigationBar.shadowImage = [[[UIImage alloc] init] autorelease];

controller is a UINavigationController.



回答5:

General, non-NDA-infringing answer:

If you don't want something sticking out of a layer, mask the layer to its bounds.

[self.layer setMasksToBounds:YES];

Set the height explicitly to 44 (or 32 for landscape on iPhone) if that doesn't work on its own.



回答6:

Setting the shadowImage to a null image does work, however, the way the solution is presented results in adding a property if the OS is earlier than iOS 6.

A better way to do something that is dependent on the existence of a property or method is:

if ([self.navigationController.navigationBar
respondsToSelector:@selector(shadowImage)]) {
self.navigationController.navigationBar.shadowImage = [[[UIImage alloc] init] autorelease];
}


回答7:

There are two possible solutions, the second of which is mentioned in other answers.

  1. Add a single, transparent, pixel at the bottom of your navigation bar background image, making it 45pt tall. This disables the shadows in iOS 6.
  2. Implement the following code:

    // Omit the conditional if minimum OS is iOS 6 or above
    if ([UINavigationBar instancesRespondToSelector:@selector(setShadowImage:)]) {
        [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
    }
    

Source: Advanced Appearance Customization on iOS, @27:15



回答8:

Since self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init]; not working, I've found an easy and workable way to remove the shadow of UINavigationBar in both iOS 6 AND iOS 5. Hope people who need can see this post.

All you have to do is prepare one background image that the height is 1 pixel larger than your navigation bar height (e.g. 320×45 for default UINavigationBar, 640×90 for 2x of course).

Then just use [[UINavigationBar appearance] setBackgroundImage: ...], you will find shadow is replaced by that 1 pixel. cheers!

BTW I found Twitter has done the exactly same thing, if you unzip Twitter.ipa and look into bg_nav_bar_events_dark.png, the size is 320×47. They made their own shadow for 3 pixels :)



回答9:

I cannot comment so I'll add my information here.

Perhaps the above suggestions worked in the beta, but it does not seem to be the case now.

self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];

The above does not work, neither do any of the other similar answers above. I have tried them all.

Clipping to bounds does work but doesn't give the result I want as I'd like other views to hang outside the nav bar.



回答10:

I came across this SO question when trying to get nav bars to look the same between iOS6 and iOS7.

The answer I found worked was simply to use:

    NSMutableDictionary *titleBarAttributes = [NSMutableDictionary dictionaryWithDictionary: [[UINavigationBar appearance] titleTextAttributes]];
    [titleBarAttributes setValue:[NSNumber numberWithInt:0] forKey:UITextAttributeTextShadowOffset];
    [[UINavigationBar appearance] setTitleTextAttributes:titleBarAttributes];

ie: set the shadow offset to zero.



回答11:

I had the same problem and I've solved it by following:

CustomNavBar *navBar = (CustomNavBar *)self.navigationController.navigationBar;
        [navBar setBackgroundImage:[UIImage imageNamed:@"navigation_bar_gray.png"] forBarMetrics:UIBarMetricsDefault];
        navBar.shadowImage = [[UIImage alloc]init]; // this is what acctually removed the shadow under navigation bar 


回答12:

How about the alternative way:

UINavigationBar.appearance().barStyle = .Black

For the dark navigation bars iOS doesn't show the shadow.



回答13:

In Swift 3.0 this would look like this

UINavigationBar.appearance().shadowImage = UIImage ()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)