在iOS7半透明导航栏中获得正确的颜色


71

如何为iOS 7中的半透明导航栏获得正确的颜色?导航栏只是将给定的颜色调整为一种更加明亮的颜色。更改亮度或颜色饱和度也无法获得正确的结果。

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

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

编辑:现在发布到Apple BugReporter


1
我认为使用iOS 7.0.3不再需要此功能,因为它现在可以设置正确的颜色。您可以玩alpha,但是这里发布的计算器可以帮助您。
法比奥·奥利维拉

Answers:


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

2
谢谢,并为计算器+1!基本上是这样说的:在任何RGB值中,您都不能拥有比102更暗的颜色。这很糟糕,因为我的管理层不允许我选择公司以外的任何其他颜色(RGB 181、27、32),只是因为苹果要求这样做。还有另一种方法,因为Facebook也更暗,在其应用程序的当前版本中它具有RGB 65,95,156。
stk 2013年

1
您仍然可以做更深的颜色,缺点是您需要添加底图以使事物变暗,这意味着您越暗,模糊将变得越弱。我设法用以下代码重新创建了65,96,156的Facebook模糊效果。我通过反复试验来做到这一点,目的是使colourView的alpha尽可能低。img707.imageshack.us/img707/3151/482w.png
SomeGuy 2013年

1
我仍然在标题上加深阴影,因此要解决此问题,我添加了[[navigationBar setBackgroundColor:[[UIColor alloc] initWithWhite:0.0f alpha:0.0f]];`。似乎可以工作。
dclowd9901 2013年

1
您可能想要添加自动调整大小以支持方向更改:colourView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
Maciej Swic 2013年

4
苹果公司提供了一个文档,描述了如何“将条形色彩与您的公司或品牌色彩相匹配” developer.apple.com/library/ios/qa/qa1808/_index.html
Amio 2015年

13

您只需要更改translucent属性

navigationBar.translucent = NO;

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


4

我已经改进了代码,为叉中的iOS 7半透明UINavigationBar实现了鲜艳生动的色彩https : //github.com/allenhsu/CRNavigationController

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


2
@MatthewCrenshaw:我还发现,与iOS 7.0.3,@AllenHsuCRNavigationController效果最好,即使你的颜色格外生动。
SwiftArchitect 2014年

这最适合我的钨色导航栏上的iOS 8
lifjoy

3

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

在此处输入图片说明

我实际上应该使用通用RGB时,将我的设置为sRGB IEC6196-2.1。


1
哇,你让我开心!那解决了我的问题。非常感谢!
Perjan Duro

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



2

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

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

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很棒!
Gamec

1
差不多五年后,这个被低估的答案仍然是唯一的“正确”解决方案(就此问题而言,任何解决方案都是“正确”的)。令人困惑的是,苹果在此方面的建议相当于“自己弄清楚”。感谢您编写BarTintColorOptimizer!
嘶嘶作响的光束

1

我想您已经阅读了上面的所有评论。如果要获取自定义背景和半透明,则应重写navigationbar类并实现自己的layoutsubviews方法。只需在此处添加其他子视图。重要说明:您应该将其添加到NavigationBar的背景子视图的上方。如果将标题或按钮放在所有子视图上方,它将隐藏您的标题或按钮。

另外,看看这个问题


1
avishic在您回答1.5天之前就提供了这种方法。如果我错了,请纠正我...
stk

1
不完全一样。他正在将newSubview移到导航栏的所有子视图之后。但是您应该将其放置在原始导航栏背景的上方,该背景仍然是最后一个子视图。
gleb.kudr 2013年

1

适用于我的简单/快速解决方案。只需在情节提要中而不是背景中设置条形色彩即可。

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

然后单击右侧的属性检查器,然后设置“ Bar Tint”
酒吧色调

您可以选择一种预定义的颜色或单击该颜色以将其设置为其他颜色。
在此处输入图片说明


0

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

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


1
这不起作用,因为它不覆盖状态栏下方的区域,并且还显示接近导航栏底部的渐变。
伊恩·霍尔

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以获得所需的确切颜色。同样,颜色当然取决于您内容视图的背景颜色(例如白色)。


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完成了工作,但是您可以使用它。


1
推送视图控制器中的“后退”按钮对于此代码不再起作用,尽管“ Done”可以正常工作
Nik


1
您应该在NavigationBar的背景视图上方添加子视图。后退按钮就可以了。
gleb.kudr 2013年

0

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

UINavigationBar.appearance().translucent = false

这将导致出现实心的条形颜色,OP明确不希望这样做。
Michael Peterson

0

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

通过再添加21%,我可以显着改善色彩匹配。不幸的是,我们的颜色首先要达到80以上的饱和度,因此将其推高至100%以上会使收益递减,并且无法完美匹配,但是距离更近。

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

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


0

您可以在模拟器中运行该应用程序,并使用吸管工具为导航栏着色。

在此处输入图片说明


0

我到处看了很多,但实际上这些都没有为我工作,解决方案如下:

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

2-运行模拟器并打开您的应用程序,在Mac中打开数字色度计,然后选择下拉菜单“以通用RGB显示”。

在此处输入图片说明

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

4-转到情节提要,然后选择背景色,并确保将其放在RGB滑块上,然后将颜色放在此处,您将获得与导航栏完全相同的颜色。

在此处输入图片说明

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

希望这可以帮助你。


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

这里取


1
仅当在NavigationBar中未设置标题时,此方法才有效。如果您设置了标题,则colorView将其变暗。
stk

1
此代码使导航栏的图层对应于z轴,并进一步框框对您创建的图层进行调整。基本上是坏方法。为此,您需要创建导航栏子类,以通过覆盖其layoutSubviews方法来正确处理导航栏上的子视图。
Eugene Dudnyk

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

1
您还阅读其他答案吗?在您回答之前,“向导航栏添加图层”方法至少发布了两次。
stk 2013年

-4

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


1
抱歉,但我明确指出,我需要酒吧是半透明的。
stk 2013年

1
Facebook也不是半透明的。是什么让你这么说呢?如果您希望条形是半透明的,则无法获得真实的颜色,因为它的alpha值<0
user1529956 2013年

1
只需在NavigationBar下滚动图像,您就会发现它是半透明的。
stk 2013年

1
Facebook酒吧是半透明的。显然,iPhone 4告诉人们每个人都不会厌倦Facebook酒吧。
Leo Natan

1
我有iPhone 5,但它对我来说并不是半透明的。不知道为什么会有所不同。
user1529956 2013年

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

1
这将导致透明但不透明的NavigationBar。zh.wikipedia.org/wiki/Transparency_and_translucency
stk 2013年

1
好的,然后填写苹果的错误报告,并要求设计人员提供适当的背景图像(如果系统所需的半透明不是您想要的)。
Eugene Dudnyk

1
抱歉,但是您的方法只能让我透明。没有任何模糊效果。当您设置navigationBar.translucent = YES时,半透明(用Apple讲)会继承类似NavigationBar等的模糊效果。
stk 2013年

1
嗨,您好!我的职位太残忍了-1。这是完全正确的,透明度是半透明的部分情况。如果您对无用的答案感到无聊,那么此社区不适合您。
尤金·杜德尼克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.