2010-07-14 26 views
16

Tengo una aplicación para iPhone que usa UINavigationController y me gustaría personalizar los elementos con imágenes de fondo personalizadas. Yo era capaz de hacer esto para el UINavigationController'sUINavigationBar con bastante facilidad utilizando categorías de Objective-C de la siguiente manera:UINavigationController personalizado UIToolbar Imagen de fondo

http://foobarpig.com/iphone/uinavigationbar-with-solid-color-or-image-background.html

me gustaría hacer lo mismo para el UINavigationController'sUIToolbar, pero no parece el mismo enfoque para trabajar (aunque no tengo ni idea por qué no). He mirado alrededor y la gente parece sugerir la subclasificación UIToolbar, pero esto no es posible para la barra de herramientas UINavigationController's, que es de solo lectura UIToolbar. Quiero utilizar la barra de herramientas UINavigationController's en lugar de solo hacer una barra de herramientas de subvista porque estoy usando la animación setToolbarHidden deslizante.

Alguien tiene alguna idea de si es posible aplicar una imagen de fondo a esta barra de herramientas UINavigationController (probablemente anulando de algún modo el método drawRect)?

Respuesta

9

Es necesario crear una subclase en lugar de crear una categoría.

No estoy muy seguro de por qué una categoría funciona para UINavigationBar pero no UIToolbar, pero la subclasificación funciona para ambos y creo que es la manera más estándar de personalizar cosas como esa.

Así subclase UIToolbar, crear una clase llamada MyToolbar (o algo similar) y poner esto en el .h:

#import <UIKit/UIKit.h> 
#import <Foundation/Foundation.h> 

@interface MyToolbar : UIToolbar {} 

- (void)drawRect:(CGRect)rect; 

@end 

Y esto en el fichero .m:

#import "MyToolbar.h" 

@implementation MyToolbar 

- (void)drawRect:(CGRect)rect { 
    backgroundImage = [UIImage imageNamed:@"my-awesome-toolbar-image.png"]; 
    [backgroundImage drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
} 

@end 

Desde allí, debe decirle al Controlador de navegación que use MyToolbar en lugar de UIToolbar. La forma más fácil que he encontrado para hacerlo es seleccionar su Controlador de navegación en el Creador de interfaz, luego en el Inspector de atributos, marcar la casilla 'Mostrar barra de herramientas'. La barra de herramientas debería aparecer en la ventana NavigationController. Haga clic en él y luego en el Inspector de identidad cambie la clase a MyToolbar.

+3

¡Estupendo! Gracias. ¿Conoces (o alguien más) una forma de hacer el último paso programáticamente? No tengo mi controlador de navegación configurado con Interface Builder. – Chris

+2

@Chris, también me gustaría saber cómo sobrescribir la barra de herramientas mediante programación. ¡Gracias! – pixelfreak

+1

¿Alguien encontró cómo el último paso se puede hacer programáticamente? – Panos

10

Actualización:

En iOS 5.0+ ahora se puede utilizar UIAppearance de personalizar la barra de navegación.


Otra manera de hacer esto es simplemente crear una categoría para la clase de su aplicación UINavigationBar. Esto fue bastante sencillo de implementar:

Interfaz:

@interface UINavigationBar (TENavigationBar) 

- (void) drawRect:(CGRect)rect; 

@end 

Implementación:

@implementation UINavigationBar (TENavigationBar) 

- (void) drawRect:(CGRect)rect 
{ 
    UIImage *image = [UIImage imageNamed:@"navigation_background"]; 

    [image drawInRect:CGRectMake(0, 
           0, 
           self.frame.size.width, 
           self.frame.size.height)]; 
} 

@end 

entonces esto será a nivel mundial aplica a todos sus UINavigationBar 's de forma automática.

+1

Desafortunadamente esto personaliza la barra de navegación y NO la barra de herramientas. –

+0

Guau, buen punto. Eché de menos la marca en este caso. Aún así, es una buena solución para la barra de navegación :) – Maurizio

+0

Agregué dos archivos a mi código, UINavigationBar.h y UINavigationBar.m y les agregué este código. También probé con los nombres de archivo JHNavigationBar.h/.m. No fue aplicado automáticamente para mí. ¿Qué me estoy perdiendo? – joshholat

2

Una de las mejores soluciones es crear una categoría de UINavigationBar y UIToolbar. Las siguientes clases le da una solución para iOS 4.0 y iOS 5.0 Compatibilidad:

Lo único es que es necesario llamar a los siguientes métodos en su viewDidLoad por ejemplo:

// Customizacion de navigation bar y toolbar compatible con iOS4 e iOS5 
[UINavigationBar iOS5UINavigationBarBackgroundImage]; 
[UIToolbar iOS5UIToolbarBackgroundImage];  

Por lo tanto, la categoría de clase para iOS 4.0 y compatibilidad con iOS 5.0 para personalizar los resultados de BackgroundImage como sigue:

@implementation UINavigationBar (BackgroundImage) 
- (void)drawRect:(CGRect)rect 
{  
    UIImage* img = [UIImage imageNamed: @"navigation-bg.png"]; 
    [img drawInRect: CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
    [self setTintColor:UIColorFromRGB(0x5ca666)];  
} 
+ (void) iOS5UINavigationBarBackgroundImage 
{ 
    if ([UINavigationBar respondsToSelector: @selector(appearance)]) 
    { 
     [[UINavigationBar appearance] setBackgroundImage: [UIImage imageNamed: @"navigation-bg.png"] forBarMetrics: UIBarMetricsDefault]; 
     [[UINavigationBar appearance] setTintColor:UIColorFromRGB(0x5ca666)]; 
    } 
} 
@end 

@implementation UIToolbar (BackgroundImage) 
- (void)drawRect:(CGRect)rect 
{ 
    UIImage *image = [UIImage imageNamed: @"toolbar-bg.png"]; 
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
    [self setTintColor:UIColorFromRGB(0x5ca666)]; 
} 
+ (void) iOS5UIToolbarBackgroundImage 
{ 
    if ([UIToolbar respondsToSelector: @selector(appearance)]) 
    { 
     [[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed: @"toolbar-bg.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault]; 
     [[UIToolbar appearance] setTintColor:UIColorFromRGB(0x5ca666)]; 
    } 
} 
@end 

¡Hola!

0

Una opción sencilla es subclase UINavigationBar/UIToolbar e inicializar el controlador de navegación usando el método:

- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass

Sin embargo, para las personalizaciones simples (como imágenes de fondo, sombras, etc.) que recomendaría a use el patrón de protocolo UIAppearance.