Skip to content

Instantly share code, notes, and snippets.

@aprato
Last active July 13, 2018 00:23
Show Gist options
  • Save aprato/6631390 to your computer and use it in GitHub Desktop.
Save aprato/6631390 to your computer and use it in GitHub Desktop.
Darker iOS7 translucent UINavigationBar
// .h
@interface AMPNavigationBar : UINavigationBar
@property (nonatomic, assign) CGFloat extraColorLayerOpacity UI_APPEARANCE_SELECTOR;
@end
// .m
@interface AMPNavigationBar ()
@property (nonatomic, strong) CALayer *extraColorLayer;
@end
static CGFloat const kDefaultColorLayerOpacity = 0.5f;
@implementation AMPNavigationBar
- (void)setBarTintColor:(UIColor *)barTintColor
{
[super setBarTintColor:barTintColor];
if (self.extraColorLayer == nil) {
// this all only applies to 7.0 - 7.0.2
if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0.3" options:NSNumericSearch] == NSOrderedAscending) {
self.extraColorLayer = [CALayer layer];
self.extraColorLayer.opacity = self.extraColorLayerOpacity;
[self.layer addSublayer:self.extraColorLayer];
}
}
self.extraColorLayer.backgroundColor = barTintColor.CGColor;
}
- (void)layoutSubviews
{
[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);
}
}
- (void)setExtraColorLayerOpacity:(CGFloat)extraColorLayerOpacity
{
_extraColorLayerOpacity = extraColorLayerOpacity;
[self setNeedsLayout];
}
#pragma mark - NSCoding
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super initWithCoder:decoder];
if (self) {
_extraColorLayerOpacity = [[decoder decodeObjectForKey:@"extraColorLayerOpacity"] floatValue];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[super encodeWithCoder:encoder];
[encoder encodeObject:@(self.extraColorLayerOpacity) forKey:@"extraColorLayerOpacity"];
}
@end
// the easy way to use it is to subclass UINavigationController and override:
- (id)initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithNavigationBarClass:[APNavigationBar class] toolbarClass:[UIToolbar class]];
if (self) {
self.viewControllers = @[ rootViewController ];
}
return self;
}
@chaitanyagupta
Copy link

This fails when the device is rotated to landscape orientation. Instead of computing spaceAboveBar from the bar's frame, its better to get the status bar's height directly using CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]). Fork here: https://gist.github.com/chaitanyagupta/7024530

@aprato
Copy link
Author

aprato commented Oct 25, 2013

check the new comment, 7.0.3 changed things again. I'm only using the backing layer pre 7.0.3. For everything later a color with an alpha (I'm using .91 on blackColor) seems to be a better approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment