2011-05-09 15 views
36

Vorrei sapere creare ombreggiatura per UINavigationbar. Ho provato a creare uno sfondo personalizzato della barra di navigazione con ombra esterna, ma l'ombra esterna copre la vista di sfondo.Come creare ombreggiatura UINavigationBar

@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 

Mostra ombreggiatura per il pulsante della barra di navigazione, ma non la barra di navigazione stessa.

Soluzione finale: Ecco come creare l'ombra esterna per UINavigationBar. Un grande grazie per MusiGenesis per sottolineare l'anello mancante del mio codice:

#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 

** Ricordatevi di importare QuartzCore o getterà errore.

+0

rapido FYI, penso di chiamare '[super willMoveToWindow: ..]' è ridondante in una categoria – Sam

+0

Ah..yes esso è. L'ho modificato. Grazie. – TonyTakeshi

+0

questo mi ha aiutato molto - grazie! – boz

risposta

28

In applyDefaultStyle, provare aggiungendo questa linea:

self.layer.masksToBounds = NO; 

Il valore predefinito per questa proprietà è YES, il che significa che anche se l'ombra è reso, non sarà reso fuori dei confini della vista , il che significa che effettivamente non lo vedi affatto.

Se state animando questo punto di vista in qualche modo, si dovrebbe anche aggiungere questa riga:

self.layer.shouldRasterize = YES; 

... a meno che non si desidera l'animazione ad essere lenta e scatti.

+0

Grazie fratello!Mi hai risparmiato un sacco di tempo prima di abitare nel disegnare l'ombra con il quarzo. Non mi aspettavo che fosse così facile. – TonyTakeshi

+0

Sono un grande fan delle ombre cadenti, e ho vissuto la stessa cosa chiedendomi perché le mie ombre non si fossero mai mostrate. – MusiGenesis

44

Se si applica un'ombra esterna a un UINavigationBar, l'ombra è ritagliato in seguito agli angoli:

clipped shadow

Questo è solo come ombre si comportano in rettangoli. Io di solito creare un percorso per l'ombra che è un po 'più ampia rispetto alla barra di navigazione vera e propria, che crea un effetto che è più simile a quello che ci si solito si aspetta:

@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. Grazie per questo. –

+0

suggeriresti questo aggiungendo un "shadow" -png come sottovista. Sto chiedendo dal punto di vista delle prestazioni – carbonr

+0

Se imposti 'shouldRasterize = YES', non penso ci siano differenze di prestazioni percepibili. Questo approccio funziona bene anche con la rotazione, anche se suppongo che l'approccio imageView funzioni se si utilizza un CGRect più ampio. –

9

Dal iOS 6.0, UINavigationBar ha uno ShadowImage struttura:

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

che ovviamente semplifica enormemente questo compito molto comune: D

-1

I bastone dell'ombra codice disegno in una funzione per mantenere pulito loadView. Puoi passare nell'oggetto su cui vuoi disegnare l'ombra se vuoi che tutte le ombre siano coerenti.

- (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; 
}