Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shadow effect for UINavigationbar like GameCenter

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??

like image 437
Shunter1112 Avatar asked Dec 01 '10 05:12

Shunter1112


3 Answers

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.

like image 143
marcio Avatar answered Sep 28 '22 00:09

marcio


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.

like image 31
Bartosz Ciechanowski Avatar answered Sep 28 '22 00:09

Bartosz Ciechanowski


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;
like image 35
Max MacLeod Avatar answered Sep 28 '22 00:09

Max MacLeod