如何在iOS 6中禁用自定义背景图像导航栏的阴影?

50

在iOS 6中,即使您设置了自定义背景图像,导航栏似乎也会自动添加一个下拉阴影。 我相信这在iOS 5中不是这种情况,因为当我在iOS 5和6模拟器中测试相同的代码时,在iOS 6中出现阴影但在iOS 5中则没有。

有人知道这方面的信息吗?或者如何启用/禁用它?


1
iOS 6是一款测试版、预发布软件,我非常确定它现在受到NDA的保护。 - Alladinian
我会删除这个问题,以避免获得所有的NDA评论,并在苹果为预发布软件提供的开发者论坛上发布它。https://devforums.apple.com/community/ios - Bill Burgess
请再次观看UI定制会话视频。 - David Rönnqvist
David是正确的 - UI自定义视频涵盖了这个确切的主题。 - Cthutu
13个回答

141

将此代码放置于您的AppDelegate中

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

评论中更新的Swift版本

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

15
注意:如果要显示自定义阴影图像,则必须使用setBackgroundImage:forBarMetrics:方法设置自定义背景图像。如果使用默认背景图像,则无论此属性的值如何,都将使用默认阴影图像。 - Mike Pollard
1
这是正确的答案。self.navigationBar.shadowImage = nil;并不像答案中描述的技术产生相同的效果。 - bithavoc
你可能想在[[UIImage alloc] init]中添加一个autorelease。 - Bas Holtrop
6
@BasHoltrop 自动释放?中世纪已经过去了。 :) - Rudolf Adamkovič
15
iOS7及以上版本的完整解决方案是:[[UINavigationBar appearance] setShadowImage:[UIImage new]]; [[UINavigationBar appearance] setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; - thgc
这对我在 iPhone 6 Plus 模拟器 上很有帮助:[[UINavigationBar appearance] setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; - Almas Adilbek

57

我知道上面有更复杂的解决方法,但这是最快最简单的方法,我将阴影隐藏在导航栏下面。

self.navigationController.navigationBar.clipsToBounds = YES;

除旋转时阴影回归外,该程序运行良好。Dima Korbin上面的答案似乎是最完整的修复方法。 - janineanne
25
在iOS 7上,这也会隐藏状态栏 :( - d2burke
运行良好,其他答案在iOS 6应用程序上出了问题,但这个应用程序也可以在iOS 7上运行 :) - Jack Solomon

25

关于shadowImage属性,以下是Apple开发文档中的说明:

讨论: 默认值为nil,对应默认阴影图像。当非nil时,此属性表示要显示而不是默认阴影的自定义阴影图像。要显示自定义阴影图像,还必须使用setBackgroundImage:forBarMetrics:方法设置自定义背景图像。如果使用默认背景图像,则无论此属性的值如何,都将使用默认阴影图像。

因此,要使用nil UIImage hack,您还必须设置自定义导航栏背景图像。这也可以是空图像,从而产生漂亮平整、清洁的“地铁”风格的导航栏:

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

19

你也可以尝试这个:

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

controller是一个UINavigationController。


4
请记住,这仅适用于iOS 6。从UINavigationBar.h中:/*默认值为nil。当非nil时,将显示自定义阴影图像,而不是默认的阴影图像...*/ @property(nonatomic,retain) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR; - José M. Gilgado

7

一般而言,与NDA无关的答案:

如果您不想让某个图层中的元素突出显示,可以将该图层裁剪为其边界范围。

[self.layer setMasksToBounds:YES];

如果仅仅设置高度不起作用,那么请明确将高度设置为44(或在iPhone上横向设置为32)。


这解决了问题,但会导致任何“显示触摸高亮”(白色发光)的UIBarButtonItems在被点击时呈现不正确。 - akaru
1
有一个更好的答案涉及到一个图像文件,但这样说可能太多了。 - Steve Cotner
那是什么属性,层? - marciokoko

6

将shadowImage设置为空图像是可行的,但是,以此解决方案的方式会在iOS 6之前的操作系统中添加属性。

更好的方法是根据属性或方法的存在性进行操作:

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

3
有两种可能的解决方案,第二种解决方案在其他答案中提到了。
  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]];
    }
    

来源: iOS上的高级外观自定义,@27:15


(翻译:Advanced Appearance Customization on iOS, @27:15)

2

由于self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];无效,我找到了一种简单有效的方法来在iOS 6和iOS 5中移除UINavigationBar的阴影。希望需要的人能看到这篇文章。

你需要准备一张背景图片,其高度比导航栏高度大1像素(例如默认的UINavigationBar为320×45,当然2x是640×90)。

然后只需使用[[UINavigationBar appearance] setBackgroundImage: ...],你会发现阴影被那1个像素替换了。干杯!

顺便说一下,我发现Twitter也做了同样的事情,如果你解压缩Twitter.ipa并查看bg_nav_bar_events_dark.png,大小为320×47。他们为3个像素制作了自己的阴影 :)


1

我无法评论,所以我会在这里添加我的信息。

也许上述建议在测试版中有效,但现在似乎不是这种情况。

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

以上方法都不起作用,其他类似的答案也都试过了。

裁剪边界确实可以起作用,但是它不能给我想要的结果,因为我希望其他视图可以悬挂在导航栏外面。


1
如何使用替代方法:
UINavigationBar.appearance().barStyle = .Black
对于深色导航栏,iOS不会显示阴影。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接