为iOS 7半透明UINavigationBar提供明亮、生动的色彩
iOS 7.1更新:此更新中似乎忽略了修改UINavigationBar中alpha通道的解决方案。目前,最好的解决方案似乎是“处理它”,并希望您选择的任何颜色都能呈现半透明效果。我仍在寻找解决这个问题的方法为iOS 7半透明UINavigationBar提供明亮、生动的色彩,ios,objective-c,uikit,uinavigationbar,ios7,Ios,Objective C,Uikit,Uinavigationbar,Ios7,iOS 7.1更新:此更新中似乎忽略了修改UINavigationBar中alpha通道的解决方案。目前,最好的解决方案似乎是“处理它”,并希望您选择的任何颜色都能呈现半透明效果。我仍在寻找解决这个问题的方法 iOS 7.0.3更新:已更新,以便在使用iOS 7.0.3时稍微解决此问题。不幸的是,没有神奇的公式支持iOS 7.0.2及更早版本和iOS 7.0.3中创建的两种颜色。苹果似乎改善了饱和度,但以不透明度为代价(因为模糊的半透明性取决于不透明度级别)。一、 与其他一些人一起,他们正在努
iOS 7.0.3更新:已更新,以便在使用iOS 7.0.3时稍微解决此问题。不幸的是,没有神奇的公式支持iOS 7.0.2及更早版本和iOS 7.0.3中创建的两种颜色。苹果似乎改善了饱和度,但以不透明度为代价(因为模糊的半透明性取决于不透明度级别)。一、 与其他一些人一起,他们正在努力为这个问题创建一个更好的解决方案
我相信很多人已经遇到过这样的问题:iOS 7会使半透明的UINavigationBar的颜色变得不饱和 我的目标是使用这种色调,但半透明的UINavigationBar: 然而,对于半透明,我得到了这个。背景视图为白色,据我所知,这将使此视图更亮: 有没有办法在保持半透明的同时达到原始颜色?我注意到Facebook已经能够让他们的酒吧变成丰富的蓝色,如下所示: …所以我知道一定有办法。背景视图在这里显然有所不同,但它们的大部分内容也是灰色/白色的。看起来,不管你把什么色条调成什么颜色,你都无法在半透明的情况下得到鲜艳的颜色 用解决方案更新。 这是我最后想到的解决方案。我采用了的解决方案,然后将自定义的
UINavigationBar
包含在UINavigationController
子类中
一种低保真方式可能是将
ui视图
固定在导航条的高度到导航条后面视图的顶部。将该视图设置为与导航栏相同的颜色,但在获得所需效果之前播放alpha:
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.navigationController.navigationBar.frame), 64)];
backgroundView.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:1 alpha:.5];
[self.navigationController.view insertSubview:backgroundView belowSubview:self.navigationController.navigationBar];
后面的风景
(将颜色从较低的示例更改为强调透明度。移动时,透明度/模糊更明显。)
子类化UINavigationBar
,并将相同的视图放在背景之上,但放在其他所有视图之后,可能会获得类似的结果,同时不那么麻烦
我见过的另一个解决方案是使用
UINavigationBar的alpha:
self.navigationController.navigationBar.alpha = 0.5f;
编辑:实际上,在测试之后,它似乎没有提供预期的行为(或任何行为):
.8阿尔法
未调整阿尔法
显然,您只希望在iOS 7设备上执行此操作。所以,在您实现任何这些之前。我没有想到这个解决方案,但它似乎工作得相当好。我刚刚将它添加到我的UINavigationController子类的viewDidLoad中
资料来源:
iOS 7.0.3更新:正如您看到的,7.0.3改变了一切。我已经更新了我的要点。希望这会随着人们的升级而消失
原始答案:
最后我把另外两个答案结合起来。我正在对UINavigationBar进行子类化,并在后面添加一个层,如果各种高度状态栏中有任何一个处于上升状态,则会有一些额外的空间来覆盖。在布局子视图中调整图层,并在设置颜色时更改颜色
要点:
退色
[super setBarTintColor:barTintColor];
if (self.extraColorLayer == nil) {
self.extraColorLayer = [CALayer layer];
self.extraColorLayer.opacity = self.extraColorLayerOpacity;
[self.layer addSublayer:self.extraColorLayer];
}
self.extraColorLayer.backgroundColor = barTintColor.CGColor;
布局子视图
[super layoutSubviews];
if (self.extraColorLayer != nil) {
[self.extraColorLayer removeFromSuperlayer];
self.extraColorLayer.opacity = self.extraColorLayerOpacity;
[self.layer insertSublayer:self.extraColorLayer atIndex:1];
CGFloat spaceAboveBar = self.frame.origin.y;
self.extraColorLayer.frame = CGRectMake(0, 0 - spaceAboveBar, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + spaceAboveBar);
}
获得所需颜色的简单方法是使用
[<NAVIGATION_BAR> setBackgroundImage:<UIIMAGE> forBarPosition:<UIBARPOSITION> barMetrics:<UIBARMETRICS>];
[setBackgroundImage:forBarPosition:barMetrics:];
只要你的图像有一些alpha,半透明性就会起作用,你可以通过改变图像来设置alpha。这是刚刚添加到iOS7中的。垂直图像的宽度和高度为640x88px(如果您希望它位于状态栏下方,则在88中添加20)。不需要这些破解:)。简单设置:
self.navigationController.navigationBar.translucent = NO;
对于iOS7,默认的半透明性保持为TRUE。我使用了@aprato的解决方案,但发现了一些新VCs的新层(例如,uinavigationItemButtonView
,UINavigationItemViews
等)将自动插入到外部层下方的位置(这将导致那些标题或按钮元素受到外彩色层的影响,因此颜色比正常情况下要暗)因此,我调整了@aprato的解决方案,强制extraColorLayer
保持在索引位置1。在索引位置1,extraColorLayer
保持在\u UINavigationBarBackground
的正上方,但在其他所有内容的下方
下面是我的类实现:
- (void)setBarTintColor:(UIColor *)barTintColor
{
[super setBarTintColor:barTintColor];
if (self.extraColorLayer == nil)
{
self.extraColorLayer = [CALayer layer];
self.extraColorLayer.opacity = kDefaultColorLayerOpacity;
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
self.extraColorLayer.backgroundColor = barTintColor.CGColor;
}
- (void)layoutSubviews
{
[super layoutSubviews];
if (self.extraColorLayer != nil)
{
self.extraColorLayer.frame = CGRectMake(0, 0 - kSpaceToCoverStatusBars, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + kSpaceToCoverStatusBars);
}
}
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview
{
[super insertSubview:view aboveSubview:siblingSubview];
[self.extraColorLayer removeFromSuperlayer];
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index
{
[super insertSubview:view atIndex:index];
[self.extraColorLayer removeFromSuperlayer];
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview
{
[super insertSubview:view belowSubview:siblingSubview];
[self.extraColorLayer removeFromSuperlayer];
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
在相关说明中,您可以通过以下方式轻松设置标题文本颜色(带阴影):
NSShadow *titleShadow = [[NSShadow alloc] init];
titleShadow.shadowOffset = CGSizeMake(0.0f, -1.0f);
titleShadow.shadowColor = [UIColor blackColor];
NSDictionary *navbarTitleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor],
NSShadowAttributeName: titleShadow};
[[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];
是否有一种方法可以使用@aprato解决方案而不必将UINavigationBar子类化
在我的项目中,我的主视图是UIViewController
问题是navigationController是一个只读属性,有没有办法在我的项目中使用you类,因为我不能使用:[[UINavigationController alloc]initWithNavigationBarClass:
谢谢我在尝试在iOS 7上设置禁用透明度的统一颜色导航栏时遇到了这个问题
在使用barTintColor进行了一段时间的实验后,我发现一种非常简单的不透明导航栏的方法是制作一个所需颜色的单像素图像,并将其制作成可拉伸图像,然后将其设置为导航栏的背景图像
UIImage *singlePixelImage = [UIImage imageNamed:@"singlePixel.png"];
UIImage *resizableImage = [singlePixelImage resizableImageWithCapInsets:UIEdgeInsetsZero];
[navigationBar setBackgroundImage:resizableImage forBarMetrics:UIBarMetricsDefault];
三行代码,非常简单,可在iOS 6和iOS 7上使用(iOS 6不支持BartinColor)。使用并增加饱和度参数,而不是以该格式创建UIColor对象。
- (void)setBarTintColor:(UIColor *)barTintColor
{
[super setBarTintColor:barTintColor];
if (self.extraColorLayer == nil)
{
self.extraColorLayer = [CALayer layer];
self.extraColorLayer.opacity = kDefaultColorLayerOpacity;
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
self.extraColorLayer.backgroundColor = barTintColor.CGColor;
}
- (void)layoutSubviews
{
[super layoutSubviews];
if (self.extraColorLayer != nil)
{
self.extraColorLayer.frame = CGRectMake(0, 0 - kSpaceToCoverStatusBars, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + kSpaceToCoverStatusBars);
}
}
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview
{
[super insertSubview:view aboveSubview:siblingSubview];
[self.extraColorLayer removeFromSuperlayer];
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index
{
[super insertSubview:view atIndex:index];
[self.extraColorLayer removeFromSuperlayer];
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview
{
[super insertSubview:view belowSubview:siblingSubview];
[self.extraColorLayer removeFromSuperlayer];
[self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}
NSShadow *titleShadow = [[NSShadow alloc] init];
titleShadow.shadowOffset = CGSizeMake(0.0f, -1.0f);
titleShadow.shadowColor = [UIColor blackColor];
NSDictionary *navbarTitleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor],
NSShadowAttributeName: titleShadow};
[[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];
UIImage *singlePixelImage = [UIImage imageNamed:@"singlePixel.png"];
UIImage *resizableImage = [singlePixelImage resizableImageWithCapInsets:UIEdgeInsetsZero];
[navigationBar setBackgroundImage:resizableImage forBarMetrics:UIBarMetricsDefault];
navigationBar.barTintColor = [UIColor colorWithHue:0.555f saturation:1.f brightness:0.855f alpha:1.f];
UINavigationController *navViewController = [[UINavigationController alloc] initWithNavigationBarClass:[C360NavigationBar class] toolbarClass:nil];
if ([navViewController.view respondsToSelector:@selector(setTintColor:)]) {
//iOS7
[navViewController.view setTintColor:self.navBarTintColor];
[[C360NavigationBar appearance] setItemTintColor:self.navBarItemTintColor];
} else {
//iOS6
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:NO];
navViewController.navigationBar.tintColor = self.navBarTintColor;
}
[navViewController pushViewController:frontViewController animated:NO];
self.window.rootViewController = navViewController;
if(IS_IOS7)
{
self.navigationController.navigationBar.barTintColor = [UIColor blackColor];
self.navigationController.navigationBar.translucent = NO;
}
else
{
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
}
#define IS_IOS7 ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0)
// this is complete 100% transparent image
self.imageBlack = [[UIImage imageNamed:@"0102_BlackNavBG"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 2, 0, 2)
resizingMode:UIImageResizingModeStretch];
// this is non-transparent but iOS7
// will by default make it transparent (if translucent is set to YES)
self.imageRed = [[UIImage imageNamed:@"0102_RedNavBG"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 2, 0, 2)
resizingMode:UIImageResizingModeStretch];
// some navigation controller
[nvCtrLeft.navigationBar setBackgroundImage:self.imageRed
forBarMetrics:UIBarMetricsDefault];
// some another navigation controller
[nvCtrCenter.navigationBar setBackgroundImage:self.imageRed
forBarMetrics:UIBarMetricsDefault];