I want to add shadow effect for UINavigationbar like GameCenter.
I think apply background image with shadow to nav bar, but title's line height would be down. And I draw shadow to background, but background image would not scroll.
What is the best Practice of this case??
You can subclass UINavigationController and then have a shadow layer for each navigation or if your bar is always visible just add the shadow to UIWindow (only one for the entire application) and then make it the frontmost view each time you add a subview.
CGColorRef darkColor = [[UIColor blackColor] colorWithAlphaComponent:.5f].CGColor;
CGColorRef lightColor = [UIColor clearColor].CGColor;
CAGradientLayer *newShadow = [[[CAGradientLayer alloc] init] autorelease];
newShadow.frame = CGRectMake(0, self.navigationBar.frame.size.height, self.navigationBar.frame.size.width, 10);
newShadow.colors = [NSArray arrayWithObjects:(id)darkColor, (id)lightColor, nil];
[self.navigationBar.layer addSublayer:newShadow];
If you choose the latter case then override the didAddSubview to make the layer the frontmost:
CALayer *superlayer = self.shadowLayer.superlayer;
[self.shadowLayer removeFromSuperlayer];
[superlayer addSublayer:self.shadowLayer];
Hope it helps.
It's easly done with custom subclass of UINavigationController. The key is to overwrite -viewWillAppear: and add sublayer to UINavigationController's view's layer:
- (void)viewWillAppear:(BOOL)animated
{
CGColorRef darkColor = [[UIColor blackColor] colorWithAlphaComponent:.5f].CGColor;
CGColorRef lightColor = [UIColor clearColor].CGColor;
CGFloat navigationBarBottom;
navigationBarBottom = self.navigationBar.frame.origin.y + self.navigationBar.frame.size.height;
CAGradientLayer *newShadow = [[[CAGradientLayer alloc] init] autorelease];
newShadow.frame = CGRectMake(0,navigationBarBottom, self.view.frame.size.width, 10);
newShadow.colors = [NSArray arrayWithObjects:(id)darkColor, (id)lightColor, nil];
[self.view.layer addSublayer:newShadow];
[super viewWillAppear:animated];
}
navigationBarBottom accounts for both UINavigationBar and status bar. Credit for gradient layer parameters goes to marcio.
Drawing a CAGradientLayer
gives a very uniform, but - in my opinion - a rather unnatural looking shadow.
Here's an alternative approach based upon the answer to question UIView with shadow.
It uses the various shadow properties of CALayer
to give the shadow effect:
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.layer.shadowColor = [[UIColor blackColor] CGColor];
self.navigationController.navigationBar.layer.shadowOffset = CGSizeMake(0.0f,0.0f);
self.navigationController.navigationBar.layer.shadowOpacity = 1.0f;
self.navigationController.navigationBar.layer.shadowRadius = 4.0f;
}
The same technique works with the tabBarController
's tabBar
;
self.tabBarController.tabBar.layer.shadowColor = [[UIColor blackColor] CGColor];
self.tabBarController.tabBar.layer.shadowOffset = CGSizeMake(0.0f,0.0f);
self.tabBarController.tabBar.layer.shadowOpacity = 1.0f;
self.tabBarController.tabBar.layer.shadowRadius = 4.0f;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With