71

如何在 iOS 7 中为我的半透明导航栏获得正确的颜色?导航栏只是将给定的颜色调整为更亮的颜色。改变颜色的亮度或饱和度也不会产生正确的结果。

有人遇到同样的麻烦吗?它似乎以某种方式起作用,看看 Facebook:他们有自己的颜色和半透明的导航栏。

编辑:只是为了说清楚:我需要 Bar 是半透明的,不透明(带有一些 alpha),而不是实心!http://en.wikipedia.org/wiki/Transparency_and_translucency

编辑:现在发布到 Apple BugReporter

4

20 回答 20

81

该栏将调整您的颜色值。

首选方法,仅适用于 RGB >= 40,会产生最模糊

您可以使用此计算器并输入您希望在屏幕上呈现的颜色,它会告诉您设置 barTintColor 的颜色,因此当 Apple 调整它时,它将按预期显示

https://www.transpire.com/insights/blog/bar-color-calculator/

编辑:请注意,这些计算适用于白色背景和较浅的颜色(超过 40 的 rgb,如果您需要更暗,则需要像其他人提到的那样添加背景图层 - 尽管这会减少条形图的模糊)

深入指南:https ://www.transpire.com/insights/blog/custom-ui-navigationbar-colors-ios7/

片段:

@interface UnderlayNavigationBar : UINavigationBar

@end

.

@interface UnderlayNavigationBar ()
{
    UIView* _underlayView;
}

- (UIView*) underlayView;

@end

@implementation UnderlayNavigationBar

- (void) didAddSubview:(UIView *)subview
{
    [super didAddSubview:subview];

    if(subview != _underlayView)
    {
        UIView* underlayView = self.underlayView;
        [underlayView removeFromSuperview];
        [self insertSubview:underlayView atIndex:1];
    }
}

- (UIView*) underlayView
{
    if(_underlayView == nil)
    {
        const CGFloat statusBarHeight = 20;    //  Make this dynamic in your own code...
        const CGSize selfSize = self.frame.size;

        _underlayView = [[UIView alloc] initWithFrame:CGRectMake(0, -statusBarHeight, selfSize.width, selfSize.height + statusBarHeight)];
        [_underlayView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
        [_underlayView setBackgroundColor:[UIColor colorWithRed:0.0f green:0.34f blue:0.62f alpha:1.0f]];
        [_underlayView setAlpha:0.36f];
        [_underlayView setUserInteractionEnabled:NO];
    }

    return _underlayView;
}

@end

.

UIViewController* rootViewController = ...;
UINavigationController* navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[UnderlayNavigationBar class] toolbarClass:nil];
[navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:0.0f green:0.0f blue:90.0f/255.0f alpha:1]];
[navigationController setViewControllers:@[rootViewController]];
于 2013-09-27T05:13:40.027 回答
13

您只需要更改translucent属性

navigationBar.translucent = NO;

它实际上与删除/制作导航栏的透明子视图/子层相同。

于 2014-09-19T09:20:55.217 回答
4

我已经改进了在我的 fork 中为 iOS 7 半透明 UINavigationBar 实现明亮、生动的颜色的代码: https ://github.com/allenhsu/CRNavigationController

通过我的修改,屏幕上的结果颜色(在白色背景上选择)将与传递给 setBarTintColor 的值完全相同。我认为这是一个了不起的解决方案。

于 2013-10-23T06:59:45.350 回答
3

我知道这个答案有点晚了,但是如果您使用的是 Interface Builder,那么在使用十六进制值时您可能会得到错误的颜色,因为 Interface Builder 设置为使用错误的颜色空间。在 Xcode 6.4 中,您可以按颜色选择器对话框右上角的小齿轮来选择您正在使用的颜色空间:

在此处输入图像描述

我的设置为 sRGB IEC6196-2.1,而实际上我应该使用 Generic RGB。

于 2015-08-17T20:05:03.633 回答
2

如果您的颜色不是特别鲜艳,您可以计算带 alpha 的等效颜色。这在 iOS 7.0.3+ 中运行良好;在 7.0.3 之前,它会自动应用 0.5 alpha。

此代码假定您的输入颜色为 RGB 且不透明,并且您的背景颜色为白色:

- (UIColor *) colorByInterpolatingForBarTintWithMinimumAlpha: (CGFloat) alpha
{
    NSAssert(self.canProvideRGBComponents, @"Self must be a RGB color to use arithmatic operations");
    NSAssert(self.alpha == 1, @"Self must be an opaque RGB color");

    CGFloat r, g, b, a;
    if (![self getRed:&r green:&g blue:&b alpha:&a]) return nil;

    CGFloat r2,g2,b2,a2;
    r2 = g2 = b2 = a2 = 1;

    CGFloat red,green,blue;

    alpha -= 0.01;
    do {
        alpha += 0.01;
        red = (r - r2 + r2 * alpha) / alpha;
        green = (g - g2 + g2 * alpha) / alpha;
        blue = (b - b2 + b2 * alpha) / alpha;
    } while (alpha < 1 && (red < 0 || green < 0 || blue < 0 || red > 1 || green > 1 || blue > 1));

    UIColor *new = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
    return new;
}

如果有人有更优雅的计算 alpha 的方法(我对那个 do-while 循环感到畏缩)我很乐意看到它:https ://gist.github.com/sgtsquiggs/7206385

于 2013-10-28T23:17:28.570 回答
2

只需使用这个简单的 barTintColor Calculator:

http://htmlpreview.github.io/?https://github.com/tparry/Miscellaneous/blob/master/UINavigationBar_UIColor_calculator.html

在此处输入图像描述

于 2015-01-20T17:14:36.607 回答
2

这是在 iOS 7.x 及更高版本中获得正确颜色的半透明导航栏的另一种方法。对于某些颜色,可以找到使半透明条显示为与所需颜色匹配的最佳条色调颜色。

例如,对于 Facebook 颜色是rgb: 65,96,156#41609c最佳颜色是#21458c。以下代码将应用程序中的所有导航栏设置为 Facebook 颜色,仅使用原生 cocoa-touch API:

UIColor* barColor = [UIColor colorWithRed:0.129995 green:0.273324 blue:0.549711 alpha:1.0]; // #21458c to make bars actual color match the #41609c color.
[[UINavigationBar appearance] setBarTintColor:barColor];

该方法的唯一限制是无法为每种可能的颜色找到优化的颜色。通常这对于深色是不可能的。

我制作了一个BarTintColorOptimizer实用程序,该实用程序应该在设备上运行,以针对您输入的任何颜色搜索优化的条形颜色。

于 2015-11-24T17:44:25.443 回答
1

我想你已经阅读了上面所有的评论。如果你想获得自定义背景和半透明,你应该重写导航栏类并实现你自己的 layoutsubviews 方法。在这里简单地添加额外的子视图。重要提示:您应该在 NavigationBar 的背景子视图上方添加它。如果您只是将其放在所有子视图之上,它将隐藏您的标题或按钮。

另外,看看这个问题

于 2013-09-25T19:30:59.107 回答
1

对我有用的简单/快速解决方案。只需在情节提要中设置条形色调而不是背景。

首先在导航控制器中选择导航栏
导航栏

然后点击右边的属性检查器然后设置Bar Tint
酒吧色调

您可以选择预定义的颜色或单击颜色将其设置为其他颜色。
在此处输入图像描述

于 2016-11-30T06:48:13.997 回答
0

要使色调颜色看起来更暗,您可以更改导航栏的背景颜色:

UIColor *color1 = [UIColor colorWithRed:55.0f/256.0f green:0.0f blue:1.0f alpha:1.0f];
[navBar setBarStyle:UIBarStyleBlackTranslucent];
[navBar setBarTintColor:color1];
UIColor *color2 = [UIColor colorWithWhite:0 alpha:0.3];
[navBar setBackgroundColor:color2];

尝试使用 color1 和 color2 来获得适合您的结果。其他任何事情都会与框架作斗争。

于 2013-09-24T09:15:54.550 回答
0
navBar.barTintColor = [UIColor orangeColor];
navBar.translucent = YES;
UIColor *backgroundLayerColor = [[UIColor redColor] colorWithAlphaComponent:0.7f];
static CGFloat kStatusBarHeight = 20;

CALayer *navBackgroundLayer = [CALayer layer];
navBackgroundLayer.backgroundColor = [backgroundLayerColor CGColor];
navBackgroundLayer.frame = CGRectMake(0, -kStatusBarHeight, navBar.frame.size.width,
        kStatusBarHeight + navBar.frame.size.height);
[navBar.layer addSublayer:navBackgroundLayer];
// move the layer behind the navBar
navBackgroundLayer.zPosition = -1;

请注意,您仍然需要使用 barTintColor 和 backgroundLayerColor 来获得您想要的确切颜色。此外,当然颜色取决于您的内容视图的背景颜色(例如白色)。

于 2013-09-24T09:53:22.247 回答
0

我已经扩展了 UINavigationController,
在它的 viewDidLoad 上,我添加了一个与色调相同的背景。

另外,我设置了背景框以覆盖状态栏区域:

    self.navigationBar.barTintColor = navBackgroundColor;
    CGRect bgFrame = self.navigationBar.bounds;
    bgFrame.origin.y -= 20.0;
    bgFrame.size.height += 20.0;
    UIView *backgroundView = [[UIView alloc] initWithFrame:bgFrame];
    backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    backgroundView.backgroundColor = navBackgroundColor;
    backgroundView.alpha = 0.6;
    [self.navigationBar addSubview:backgroundView];
    [self.navigationBar sendSubviewToBack:backgroundView];

在我的情况下,alpha 0.6 完成了工作,但你可以使用它。

于 2013-09-24T10:37:54.410 回答
0

如果您使用的是 swift 2.0,则可以使用它,这将消除模糊并正确显示颜色。

UINavigationBar.appearance().translucent = false
于 2016-02-03T23:20:57.917 回答
0

通过比较我之前和之后的颜色,我发现饱和度下降了 21%,而色调和亮度保持不变。

通过添加 21%,我能够显着改善颜色匹配。不幸的是,我们的颜色开始时的饱和度高于 80,因此将其推到 100% 以上会导致收益递减,并且不能完美匹配,但它变得更接近了。

对于饱和度低于 80 的颜色,它应该做得更好。

有关如何调整颜色饱和度的信息 如何修改 UIColor 的色调、亮度和饱和度?

于 2017-03-30T18:57:04.480 回答
0

您可以在模拟器中运行应用程序并使用吸管工具获取导航栏的颜色。

在此处输入图像描述

于 2017-07-11T13:07:41.900 回答
0

我环顾四周,但这些都没有真正为我工作,解决方案如下:

1-设置您的导航栏TintColor(背景)。

2- 运行模拟器并打开您的应用程序,在您的 Mac 中打开Digital Color Meter并选择下拉菜单为“Display in Generic RGB”。

在此处输入图像描述

3- 使用此工具选择您将为视图设置的导航颜色。

4- 转到故事板,然后选择背景颜色并确保其在 RGB 滑块上,并将颜色放在这里,您将获得与导航栏完全相同的颜色。

在此处输入图像描述

注意: isTranslucent 是打开还是关闭都没有关系。

希望这可以帮助你。

于 2019-06-02T14:05:46.023 回答
-1

这应该有效:

UIColor *barColour = [UIColor colorWithRed:0.13f green:0.14f blue:0.15f alpha:1.00f];

UIView *colourView = [[UIView alloc] initWithFrame:CGRectMake(0.f, -20.f, 320.f, 64.f)];
colourView.opaque = NO;
colourView.alpha = .7f;
colourView.backgroundColor = barColour;

self.navigationBar.barTintColor = barColour;

[self.navigationBar.layer insertSublayer:colourView.layer atIndex:1];

取自这里

于 2013-09-20T12:52:44.477 回答
-2

这对我有用:

CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, -20,navigationBar.frame.size.width,navigationBar.frame.size.height + 20);
layer.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.75].CGColor;
layer.zPosition = -5;
[navigationBar.layer addSublayer:layer];
于 2013-09-27T20:16:08.403 回答
-4

发生这种情况是因为 navigationBar.translucent == YES。将此属性设置为 NO,它将是正确的颜色。但是,我还没有找到如何将此半透明设置应用于所有导航栏而不在每个导航栏上显式调用它。状态栏也以这种方式保持与导航栏相同的颜色。

于 2013-09-22T00:01:46.633 回答
-4

尝试为您的导航栏渲染相应的背景图像。这适用于我的测试应用程序。

UIGraphicsBeginImageContext(CGSizeMake(1, 1));
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor colorWithRed:55.0f/256.0f green:0.0f blue:1.0f alpha:0.5f] set];
CGContextFillRect(context, CGRectMake(0, 0, 1, 1));

UIImage *navBarBackgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[[UINavigationBar appearance] setBackgroundImage:navBarBackgroundImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:navBarBackgroundImage forBarMetrics:UIBarMetricsLandscapePhone];
于 2013-09-23T15:29:39.850 回答