2011-05-09 3 views
36

Хотелось бы знать, создать тень для UINavigationbar. Я попытался создать собственный фон на основе навигационной панели с теневой теневой печатью, но тень накрыть фон.Как создать UINavigationBar drop shadow

@implementation UINavigationBar (CustomImage) 
- (void)drawRect:(CGRect)rect { 
    UIImage *image = [[UIImage imageNamed:@"titleBar.png"] retain];; 
    [image drawInRect:rect]; 
    [image release]; 
} 

- (CGSize)sizeThatFits:(CGSize)size { 
    CGSize newSize = CGSizeMake(320,50); 
    return newSize; 
} 
@end 

I also tried on following solution: http://www.travisboudreaux.com/adding-a-drop-shadow-to-a-uinavigationbar: 

@interface UINavigationBar (dropshadow) 

-(void) applyDefaultStyle; 

@end 

@implementation UINavigationBar (dropshadow) 

-(void)willMoveToWindow:(UIWindow *)newWindow{ 
    [self applyDefaultStyle]; 
} 

- (void)applyDefaultStyle { 
    // add the drop shadow 
    self.layer.shadowColor = [[UIColor blackColor] CGColor]; 
    self.layer.shadowOffset = CGSizeMake(0.0, 3.0); 
    self.layer.shadowOpacity = 0.25; 
} 
@end 

Он показывает тень для моей кнопки навигационной панели, но сама панель навигации не отображается.

Окончательное решение: Вот как я создаю тень для UINavigationBar. Большое спасибо за MusiGenesis за указание недостающего звена моего кода:

#import <QuartzCore/QuartzCore.h> 

@interface UINavigationBar (CustomImage) 

-(void) applyDefaultStyle; 

@end 

//Override For Custom Navigation Bar 
@implementation UINavigationBar (CustomImage) 
- (void)drawRect:(CGRect)rect { 
    UIImage *image = [UIImage imageNamed: @"titleBar.png"]; 
    [image drawInRect:CGRectMake(0, 0, 320, 44)]; 
} 

-(void)willMoveToWindow:(UIWindow *)newWindow{ 
    [super willMoveToWindow:newWindow]; 
    [self applyDefaultStyle]; 
} 

- (void)applyDefaultStyle { 
    // add the drop shadow 
    self.layer.shadowColor = [[UIColor blackColor] CGColor]; 
    self.layer.shadowOffset = CGSizeMake(0.0, 3); 
    self.layer.shadowOpacity = 0.25; 
    self.layer.masksToBounds = NO; 
    self.layer.shouldRasterize = YES; 
} 

@end 

** Не забудьте импортировать QuartzCore или он будет бросать ошибку.

+0

Быстрый FYI, я думаю, называя '[супер willMoveToWindow: ..]' избыточна в категории – Sam

+0

Ah..yes это. Изменили его. Благодарю. – TonyTakeshi

+0

это мне очень помогло - спасибо! – boz

ответ

28

В applyDefaultStyle, попробуйте добавить следующую строку:

self.layer.masksToBounds = NO; 

Значение по умолчанию для этого свойства YES, что означает, что даже если тень оказывается, она не будет вынесена за пределы представления , что означает, что вы вообще этого не видите.

Если вы анимировать эту точку зрения в любом случае, вы должны также добавить эту строку:

self.layer.shouldRasterize = YES; 

... если вы не хотите, чтобы анимация будет медленной и прерывистым.

+0

Спасибо, брат!Вы спасли меня много времени, прежде чем жить в рисовании тени с кварцем. Я не ожидал, что это будет так просто. – TonyTakeshi

+0

Я большой поклонник тени теней, и я прошел через то же самое, удивляясь, почему мои тени никогда не появлялись. – MusiGenesis

44

Если применить тень к UINavigationBar, тень обрезается ниже по углам:

clipped shadow

Это просто, как тени ведут себя на прямоугольники. Я обычно создаю путь для тени, это немного шире, чем фактическая навигационный бар, который создает эффект, который больше похож то, что вы обычно ожидаете:

@implementation UINavigationBar (DropShadow) 

-(void)willMoveToWindow:(UIWindow *)newWindow { 
    [super willMoveToWindow:newWindow]; 
    self.layer.shadowColor = [UIColor blackColor].CGColor; 
    self.layer.shadowOpacity = 1; 
    self.layer.shadowOffset = CGSizeMake(0,4); 
    CGRect shadowPath = CGRectMake(self.layer.bounds.origin.x - 10, self.layer.bounds.size.height - 6, self.layer.bounds.size.width + 20, 5); 
    self.layer.shadowPath = [UIBezierPath bezierPathWithRect:shadowPath].CGPath; 
    self.layer.shouldRasterize = YES; 
} 

better

+1

ShadowPath. Спасибо вам за это. –

+0

вы бы предложили это, добавив «тень» -png в качестве дополнительного представления. Я спрашиваю с точки зрения производительности. – carbonr

+0

Если вы установите 'shouldRasterize = YES', я не думаю, что есть заметная разница в производительности. Этот подход также хорошо работает с поворотом, хотя я полагаю, что подход imageView будет работать, если вы используете более широкий CGRect. –

9

С прошивкой 6.0, UINavigationBar имеет свойство ShadowImage:

@property(nonatomic,retain) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR; 

, который, конечно, значительно упрощает эту очень общую задачу: D

-1

Я прилипать тень рисунок код в функцию, чтобы сохранить loadView в чистоте. Вы можете передать объект, на который хотите нарисовать тень, если хотите, чтобы все ваши тени были согласованы.

- (void)loadView 
{ 
    self.view = [[UIView alloc] init]; 
    self.view.backgroundColor = [UIColor whiteColor]; 

    [self drawShadow]; 
} 


- (void)drawShadow 
{ 
    self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; 
    self.navigationController.navigationBar.layer.shadowOpacity = 0.3; 
    self.navigationController.navigationBar.layer.shadowOffset = CGSizeMake(0, 0); 
    self.navigationController.navigationBar.layer.shadowRadius = 15; 
    self.navigationController.navigationBar.layer.masksToBounds = NO; 
}