domingo, 18 de marzo de 2012

Personalizar UINavigationBar y UIBarButtonItem con una imagen de fondo

A partir de iOS5, es posible modificar el aspecto de los UINavigationBar o UIButton de una manera sencilla.

Vamos a ver un ejemplo de cómo cambiar el color de fondo de un UINavigationBar y sus botones.

Primero tenemos que crearnos la imagen que vamos a usar como background. Tenemos que tener en cuenta que la altura en el iPhone cuando está en horizontal es 44 pixels y en modo vertical es 32. Para el iPad es 44 en cualquier orientación. La de los botones es 37 pixels.

Necesitamos crear dos imágenes diferentes para el background. En el iPhone 3 y 3GS y en el iPad 1 y 2 la cuadrícula de 320x480 pixel. Sin embargo iPhone 4, 4S e iPad3 , con su retina display,  utilizan 640x960 pixels en una pantalla del mismo tamaño. Esto significa que 1 punto = 2 pixels, con lo que la imagen se verá más nítida.

Para detectar la Retina Display en el dispositivo iOS comprobamos si la propiedad [UIScreen mainSceeen].scale es igual a 2.0:

if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && 
    ([UIScreen mainScreen].scale == 2.0)) 
    {
        //Retina Display
        /
    } else 
    {
        //No Retina Display
    }
Las guías de desarrollo iOS aconsejan que las imágenes tengan el mismo nombre y a la destinada para dispositivos con retina display añadirla el sufijo @2x

Mediante photoshop he creado un fondo como el de la siguiente imagen para la NavigationBar.








Los he llamado:

  • NavBG.png (320x44px) y
  •  NavBG@2x.png (640x88px)
Necesitamos crear una clase que herede de UINavigationBar. Vamos a llamarla CustomNavBar. Su fichero de interface será así:

@interface CustomNavBar : UINavigationBar
@end

Y en la implementación simplemente sobreescribiremos su método drawRect:

#import "CustomNavBar.h"
@implementation CustomNavBar
- (void)drawRect:(CGRect)rect 
{
    UIImage *image;
    
    if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0)) 
    {
        //Retina Display
        image = [UIImage imageNamed:@"NavBG@2x.png"];
    } else 
    {
        //No Retina Display
        image = [UIImage imageNamed:@"NavBG.png"];
    }
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end

Una vez que tengamos la clase, nos situaremos en el storyboard y accederemos a la Navigation Bar del Navigation Controller.



Y en el Identity Inspector cambiaremos la clase UINavigationBar por la nuestra, CustomNavBar, tal y como se ve en la figura:




Este será el resultado si ejecutamos nuestro código: 



Vamos a personalizar los botones Edit y Add con la siguiente imagen:

Button.png
En el viewDidLoad del MasterViewController añadiremos nuestra imagen. 

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.leftBarButtonItem = self.editButtonItem;
    
    UIImage *editButton = [[UIImage imageNamed:@"Button"resizableImageWithCapInsets:UIEdgeInsetsMake(12, 12, 12, 12)];
    [self.editButtonItem setBackgroundImage:editButton forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
    [addButton setBackgroundImage:editButton forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    self.navigationItem.rightBarButtonItem = addButton;
    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
}

Obteniendo este resultado:




No hay comentarios:

Publicar un comentario