2011-10-05 25 views

Respuesta

8

Hay algunas soluciones posibles:

solución más rápida para más perezoso de nosotros:

@interface MyNavigationBar : UINavigationBar 

@end 

@implementation MyNavigationBar 

- (void)drawRect:(CGRect)rect { 

} 

@end 

@implementation UINavigationBar (BecauseIMLazyHacks) 
/* 
Another Ugly hack for iOS 5.0 support 
*/ 
+ (Class)class { 
    return NSClassFromString(@"MyNavigationBar"); 
} 

-(void)drawRect:(CGRect)rect { 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextTranslateCTM(context, 0, self.frame.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 

    CGContextDrawImage(context, CGRectMake(0, 0, 
    self.frame.size.width, self.frame.size.height), barBackground.CGImage);  

} 
@end 

vez más. Funciona, pero no deberías hacerlo así.

Otra forma, como se sugiere en WWDC'11 es para anular UINavigationBar (Crear MyNavigationBar) e inicializar UINavigationController de xib como aquí:

http://www.iosdevnotes.com/2011/09/custom-uinavigationbars-techniques/

Y, por último, el uso del interruptor de flujo lógico iOS5.0 e iOS5.0- Use una nueva API donde sea posible.

Categorías es una ruta incorrecta, Swizzling es una ruta incorrecta. (Sólo están susurrando en sus oídos: "Dése al lado oscuro Es la única manera en que puede guardar sus aplicaciones..")

+3

El código drawRect debe estar en la implementación de MyNavigationBar, no en la Categoría. –

+0

¿Qué es ese barBackground.CGImage por cierto? No parece en ningún otro lugar en el código anterior. – Selvin

+0

barBackground tiene clase UIImage, por lo que CGIImage solo propiedad con CGImagRef de la clase UIImage. –

11

intenta leer iOS 5.0 Release Notes

En iOS 5, el Las implementaciones UINavigationBar, UIToolbar y UITabBar han cambiado de modo que no se llama al método drawRect: a menos que se implemente en una subclase. Las aplicaciones que han reimplementado drawRect: en una categoría en cualquiera de estas clases encontrarán que el método drawRect: no se llama. UIKit realiza la comprobación de enlaces para evitar que se llame al método en las aplicaciones vinculadas antes de iOS 5, pero no admite este diseño en iOS 5 o posterior.

1
@implementation UINavigationBar (MyCustomNavBar) 

- (void)setBackgroudImage:(UIImage*)image 
{ 
    CGSize imageSize = [image size]; 
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, imageSize.height); 
    UIImageView *backgroundImage = [[UIImageView alloc] initWithImage:image]; 
    backgroundImage.frame = self.bounds; 
    [self addSubview:backgroundImage]; 
    [backgroundImage release]; 
} 
@end 

El swizzling anterior le permitirá establecer cualquier imagen de fondo personalizado para el UINavigationBar (IOS5 & iOS4).

+1

Desafortunadamente, los botones desaparecen cuando haces esto. –

26

Configuración de fondo personalizado para UINavigationBar para admitir iOS5 e iOS4 también!

http://www.mladjanantic.com/setting-custom-background-for-uinavigationbar-what-will-work-on-ios5-and-ios4-too/

http://rogchap.com/2011/06/21/custom-navigation-bar-background-and-custom-buttons/


Como saben, hasta que iOS 5 salió, hemos utilizado drawRect anulación en AppDelegate de personalizar UINavigationBar. Pero sepa, iOS 5 nos da un nuevo método para el diseño (y el viejo no funciona).

Cómo crear una aplicación que funcione en iOS 4 e iOS 5 con UINavigationBar estilizado?

¡Debe hacer las dos cosas!

En AppDelegate uso este código:

@implementation UINavigationBar (UINavigationBarCategory) 
- (void)drawRect:(CGRect)rect { 
UIImage *img = [UIImage imageNamed:@"navbar.png"]; 
[img drawInRect:rect]; 
} 
@end 

y en viewDidLoad método para IOS5 (en su aplicación vista):

if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]){ 
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"navbar.png"] forBarMetrics:UIBarMetricsDefault]; 
} 

Si usted ve, aquí estamos preguntando si barra de navegación se respondToSelector a ¡evita chocar en iOS4!

+0

Esta es una solución un poco diferente. En esta solución, siempre debe configurar la barra de navegación para cada viewController. pero para iOS4 y iOS5. Es un poco mejor –

+0

Pongo el código en mi AppDelegate. Cada ViewController tiene la imagen en la barra de navegación. Parece que debe implementarlo solo una vez y no en CADA ViewController :-) – Manni

+0

En el caso del dispositivo iOS5, debe colocarlo en CADA controlador que tenga un nuevo controlador de navegación –

12

Aquí es una solución menos feo que funciona tanto para iOS4 y 5:

@implementation UINavigationBar (CustomBackground) 

- (UIImage *)barBackground 
{ 
    return [UIImage imageNamed:@"top-navigation-bar.png"]; 
} 

- (void)didMoveToSuperview 
{ 
    //iOS5 only 
    if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) 
    { 
     [self setBackgroundImage:[self barBackground] forBarMetrics:UIBarMetricsDefault]; 
    } 
} 

//this doesn't work on iOS5 but is needed for iOS4 and earlier 
- (void)drawRect:(CGRect)rect 
{ 
    //draw image 
    [[self barBackground] drawInRect:rect]; 
} 

@end 
+0

Genial, funcional y simple cuando se trata de la solución de categoría y demasiado flojo para seguir un truco de subclase. – iwalktheline

+0

¡Funcionó para mí! Gracias – ismriv

0

Siga este link Para que el código compatible con iOS4, 5 y 6.

Sólo hay que hacer en Photoshop u otro software de una forma rectangular con el tamaño de 320x44 o 640x88 (para visualización de la retina) y la importación a su proyecto

en AppDelegate utilizar este código (en la cabecera entre import y @implementation AppDelegate):

@implementation UINavigationBar (CustomImage) 
- (void)drawRect:(CGRect)rect { 
    UIImage *image = [UIImage imageNamed:@"top_bar.png"]; 
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
} 
@end 

En viewDidLoad utilizar este código para IOS5 y iOS6:

#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0 
    if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]){ 
     [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"top_bar.png"] forBarMetrics:UIBarMetricsDefault]; 
    } 
#endif 
0

Después de iOS 5 - (void)drawRect:(CGRect)rect no se llama mientras creamos categoría para UINavigationBar pero se puede llamar -(void)awakeFromNib y añadir todo el código que desea añadir.

Cuestiones relacionadas