【问题标题】:Get the right color in iOS7 translucent navigation bar在iOS7半透明导航栏中获取正确的颜色
【发布时间】:2013-09-24 13:43:13
【问题描述】:

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

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

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

编辑:现在发布到 Apple BugReporter

【问题讨论】:

  • 我认为在 iOS 7.0.3 中不再需要这个,因为它现在设置了正确的颜色。但是,您可以玩 alpha,此处发布的计算器可以帮助您。

标签: ios colors uinavigationbar ios7


【解决方案1】:

该栏将调整您的颜色值。

首选方法,仅适用于 RGB >= 40,模糊程度最高

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

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

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

深度指南: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]];

【讨论】:

  • 感谢并为计算器 +1!基本上它所说的是:在任何 RGB 值中,您都不能拥有比 102 更“暗”的颜色。这很糟糕,因为我的管理层不允许我选择公司颜色(RGB 181,27,32)以外的任何其他颜色,只是因为 Apple 要求这样做。必须有另一种方式,因为 Facebook 也更暗,在他们的应用程序的当前版本中有 RGB 65,95,156。
  • 你仍然可以做更深的颜色,缺点是你需要添加一个底层视图来使东西变暗,这意味着你越暗模糊会变得越弱。我已经设法使用以下代码重新创建了 65,96,156 的 Facebook 模糊。我通过反复试验做到了这一点,目的是让 colourView 的 alpha 尽可能低。 img707.imageshack.us/img707/3151/482w.png
  • 我的标题仍然有较深的烧伤,所以为了解决这个问题,我添加了`[navigationBar setBackgroundColor:[[UIColor alloc] initWithWhite:0.0f alpha:0.0f]];`。似乎工作。
  • 您可能想要添加自动调整大小以支持方向更改:colourView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
  • 有一份来自苹果的文件描述了如何“将酒吧色调颜色与您的公司或品牌颜色匹配”developer.apple.com/library/ios/qa/qa1808/_index.html
【解决方案2】:

您只需要更改translucent 属性

navigationBar.translucent = NO;

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

【讨论】:

    【解决方案3】:

    我在我的 fork 中改进了 Achieving bright, vivid colors for an iOS 7 translucent UINavigationBar 的代码:https://github.com/allenhsu/CRNavigationController

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

    【讨论】:

    • @MatthewCrenshaw:我仍然发现使用 iOS 7.0.3,@AllenHsu CRNavigationController 效果最好,即使您的颜色 非常鲜艳。
    • 这最适合我在 iOS 8 上的钨色导航栏。
    【解决方案4】:

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

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

    【讨论】:

    • 哇,你成就了我的一天!这解决了我的问题。非常感谢!
    【解决方案5】:

    如果您的颜色不是特别鲜艳,您可以计算带 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

    【讨论】:

      【解决方案6】:
      【解决方案7】:

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

      例如,对于 rgb: 65,96,156#41609c 的 Facebook 颜色,最佳颜色是 #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 实用程序,它应该在设备上运行,以针对您输入的任何颜色搜索优化的条形颜色。

      【讨论】:

      • BarTintColorOptimizer 很棒!
      • 差不多五年后,这个被低估的答案仍然是唯一的“正确”解决方案(只要这个问题的任何解决方案都是“正确的”)。令人费解的是,Apple 在这方面的建议相当于“自己弄清楚”。感谢您编写 BarTintColorOptimizer!
      【解决方案8】:

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

      另外,请查看this question

      【讨论】:

      • avishic 在您回答前 1.5 天就提供了这种方法。如果我错了,请纠正我...
      • 不完全一样。他正在将 newSubview 移到导航栏的所有子视图后面。但是你应该把它放在原来的导航栏背景之上,它仍然是最后一个子视图。
      【解决方案9】:

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

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

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

      您可以选择预定义的颜色或单击颜色将其设置为其他颜色。

      【讨论】:

        【解决方案10】:

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

        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 来获得适合您的结果。其他任何事情都会与框架发生冲突。

        【讨论】:

        • 这不起作用,因为它没有覆盖状态栏下方的区域,并且还显示接近导航栏底部的渐变。
        【解决方案11】:
        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 来获得您想要的确切颜色。此外,颜色当然取决于您的内容视图的背景颜色(例如白色)。

        【讨论】:

          【解决方案12】:

          我已经扩展了 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 完成了工作,但您可以使用它。

          【讨论】:

          • 推送视图控制器中的后退按钮停止使用此代码为我工作,尽管完成工作正常
          • 使用stackoverflow.com/questions/3046813/…中描述的技术解决了这个问题
          • 您应该在 NavigationBar 的背景视图上方添加子视图。并且后退按钮会很好。
          【解决方案13】:

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

          UINavigationBar.appearance().translucent = false
          

          【讨论】:

          • 这将导致纯色条形,OP 特别不希望这样。
          【解决方案14】:

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

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

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

          有关如何调整颜色饱和度的信息How can I modify a UIColor's hue, brightness and saturation?

          【讨论】:

            【解决方案15】:

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

            【讨论】:

              【解决方案16】:

              我已经看了很多,但这些都没有真正为我工作,解决方案如下:

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

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

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

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

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

              希望对你有所帮助。

              【讨论】:

                【解决方案17】:

                这应该可行:

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

                取自here

                【讨论】:

                • 这仅适用于您没有在 NavigationBar 中设置标题的情况。如果你有一个标题集,它会被 colorView 变暗。
                • 此代码使导航栏的层对应于 z 顺序和框架对您创建的层的进一步调整。基本上不好的方法。为此,您需要创建导航栏子类,以通过覆盖其 layoutSubviews 方法来正确处理导航栏上的子视图。
                【解决方案18】:

                这对我有用:

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

                【讨论】:

                • 您是否阅读了其他一些答案? 'adding-layer-to-navbar'-approach 在您的回答之前至少发布了两次。
                【解决方案19】:

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

                【讨论】:

                • 抱歉,我明确表示我需要栏是半透明的。
                • Facebooks 也不是半透明的。是什么让你这么说?如果您希望条形图是半透明的,则无法获得真实颜色,因为它的 alpha
                • 只需滚动导航栏下的图像,您就会发现它是半透明的。
                • Facebook 栏是半透明的。厌倦了人们用 iPhone 4 告诉每个人 Facebook 栏不是,其实它显然是。
                • 我有 iPhone 5,但我的手机不是半透明的。不知道为什么会有所不同。
                【解决方案20】:

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

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

                【讨论】:

                • 这会产生一个透明但不是半透明的 NavigationBar。 en.wikipedia.org/wiki/Transparency_and_translucency
                • 好的,如果系统提供的半透明不是你想要的,那么填写苹果错误报告并要求设计人员提供适当的背景图像。
                • 抱歉,我只是通过您的方法获得透明度。没有任何模糊效果。当您设置 navigationBar.translucent = YES;
                • 嘿,伙计,你对我的帖子做出-1真是太残忍了。这是完全正确的,透明是半透明的部分情况。如果您厌倦了无用的答案,那么这个社区不适合您。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多