2010-04-21 25 views
88

Quiero crear un UIBarButtonItem con una imagen personalizada, pero no quiero el borde que el iPhone agrega, ya que mi Imagen tiene un borde especial.UIBarButtonItem con imagen personalizada y sin borde

Es lo mismo que el botón Atrás, pero un botón de avance.

esta aplicación es para un proyecto de las instalaciones, por lo que no me importa si Apple rechace o apruebe o que le gusta :-)

Si utilizo el initWithCustomView: v propiedad de la UIBarButtonItem, lo puedo hacer :

UIImage *image = [UIImage imageNamed:@"right.png"]; 

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
[button setBackgroundImage: [image stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateNormal]; 
[button setBackgroundImage: [[UIImage imageNamed: @"right_clicked.png"] stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateHighlighted]; 

button.frame= CGRectMake(0.0, 0.0, image.size.width, image.size.height); 

[button addTarget:self action:@selector(AcceptData) forControlEvents:UIControlEventTouchUpInside]; 

UIView *v=[[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, image.size.width, image.size.height) ]; 

[v addSubview:button]; 

UIBarButtonItem *forward = [[UIBarButtonItem alloc] initWithCustomView:v]; 

self.navigationItem.rightBarButtonItem= forward; 

[v release]; 
[image release]; 

Esto funciona, pero si tengo que repetir este proceso en 10 vistas, esto no es SECO.

Supongo que tengo que hacer una subclase, ¿pero qué?

  • NSView?
  • UIBarButtonItem?

gracias,

cordiales,

+3

Gracias por compartir su código, eso es todo lo que necesitaba :). – Max

+1

Todo el mundo, utilicé la respuesta proporcionada por San el 6 de febrero. Me llevó los 5 minutos integrarme en mi Storyboard, y funcionó a la perfección. La propiedad Selector se encuentra en Connections Inspector of IB. Controle el arrastre desde UIButton al objeto ViewController y los métodos aparecerán. Toca el método que quieras y prácticamente has terminado. Lo único que queda sería una limpieza del código. Se usó btnXXXXX.hidden para ocultar y mostrar para reemplazar barbuttonitem = nil. Pero este método fue fácil y muy limpio. – user589642

Respuesta

44

Puede añadir un método para UIBarButtonItem sin la subclasificación utilizando categoría personalizada:

@interface UIBarButtonItem(MyCategory) 

+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action; 

@end 

@implementation UIBarButtonItem(MyCategory) 

+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action{ 
// Move your item creation code here 
} 
@end 

Así cualquier parte del código puede crear elemento de la barra de llamar este método (siempre que incluya un encabezado con su declaración).

P.S. No necesita utilizar 'v' UIView ya que puede crear UIBarButtonItem con un botón como vista personalizada directamente.
P.P.S. También necesita [liberación anticipada] en su código.

+0

PS => sí, también funciona, menos código :-) – mongeta

+0

PPS => gracias, ahora agregó – mongeta

+0

La categoría personalizada: Tengo que crear el archivo de encabezado con esas declaraciones, y el archivo de implementación, donde puse el código al que se refiere? gracias – mongeta

6

Una alternativa es la subclase UIBarButtonItem. ¿Por qué? De modo que la acción se invoca en el destino con el remitente correcto. En el código anterior, el argumento del remitente en el mensaje de acción es la instancia de UIButton, no la instancia de UIBarButtonItem. Esto sería importante, por ejemplo, si desea presentar un UIPopoverController desde el elemento del botón de la barra. Al crear una subclase de UIBarButtonItem, puede agregar un ivar que conserve el objetivo original, permitiendo que nuestras instancias de subclase intercepten, modifiquen y reenvíen el mensaje de acción con el remitente adecuado.

Así, CCFBarButtonItem.h:

#import <uIKit/UIBarButtonItem.h> 

@interface CCFBarButtonItem : UIBarButtonItem 
{ 
@protected 
    id _originalTarget; 
} 
- (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action; 
@end 

y CCFBarButtonItem.m

#import "CCFBarButtonItem.h" 
#import <UIKit/UIButton.h> 
#import <UIKit/UIView.h> 
#import <UIKit/UIImage.h> 

@implementation CCFBarButtonItem 

#pragma mark - Object life cycle 

- (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action; 
{ 
    _ASSIGN(_originalTarget, target); 

    UIButton *imgButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
    [imgButton setImage:image forState:UIControlStateNormal]; 
    imgButton.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height); 
    [imgButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; 

    self = [super initWithCustomView:imgButton]; 

    return self; 
} 

- (void)dealloc; 
{ 
    MCRelease(_originalTarget); 
    [super dealloc]; 
} 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector; 
{ 
    if([_originalTarget respondsToSelector:aSelector]) 
    { 
     return [_originalTarget methodSignatureForSelector:aSelector]; 
    } 
    else 
    { 
     return [super methodSignatureForSelector:aSelector]; 
    } 
} 

- (void)forwardInvocation:(NSInvocation *)anInvocation; 
{ 
    SEL aSelector = [anInvocation selector]; 
    if([_originalTarget respondsToSelector:aSelector]) 
    { 
     // modify the 'sender' argument so that it points to self 
     [anInvocation setArgument:&self atIndex:2]; 
     [anInvocation invokeWithTarget:_originalTarget]; 
    } 
    else 
    { 
     [self doesNotRecognizeSelector:aSelector]; 
    } 
} 
@end 
36

lo encontré esta manera fácil. Está sugerido en la parte superior. "random.png" tiene que estar en proyecto. Solo arrastre y suelte cualquier imagen.

UIButton *a1 = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [a1 setFrame:CGRectMake(0.0f, 0.0f, 25.0f, 25.0f)]; 
     [a1 addTarget:self action:@selector(randomMsg) forControlEvents:UIControlEventTouchUpInside]; 
     [a1 setImage:[UIImage imageNamed:@"config.png"] forState:UIControlStateNormal]; 
     UIBarButtonItem *random = [[UIBarButtonItem alloc] initWithCustomView:a1]; 

//? line incomplete ?// imageNamed:@"random.png"] style:UIBarButtonItemStylePlain target:self action:@selector(randomMsg)]; 

    self.navigationItem.rightBarButtonItem = random; 
+1

gracias, funciona! – offset

49

Otra solución simple es

  1. Arrastre un UIButton estándar
  2. Establecer el estilo del botón de la costumbre y establecer su imagen para ese botón
  3. arrastrarlo a la UINavigationBar Selector
  4. Conjunto
+0

Probablemente la solución más fácil. ¡Gracias! – Prine

+0

@Prine Gracias :) – san

+1

Brilliant! La única peculiaridad: no funcionaría si arrastras el botón directamente a la barra de navegación. El botón debe establecerse en personalizado antes de agregarlo a la barra de navegación. No estoy seguro por qué, pero así es como es. Entonces paso # 1 - significa arrastrar UIBatton en algún lugar de su UI que no sea la barra de navegación. –

1

Ok eso c ategoría funciona muy bien porque no hay problemas con Popovercontroller :-)

#import <UIKit/UIKit.h> 

@interface UIBarButtonItem (BarButtonItemExtended) 
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action; 
-(void)performBarButtonAction:(id)sender; 
@end 



#import "UIBarButtonItem+BarButtonItemExtended.h" 

@implementation UIBarButtonItem (BarButtonItemExtended) 

+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action 
{  
    UIButton *imgButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
    [imgButton setImage:image forState:UIControlStateNormal]; 
    imgButton.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height); 

    UIBarButtonItem *b = [[UIBarButtonItem alloc]initWithCustomView:imgButton]; 

    [imgButton addTarget:b action:@selector(performBarButtonAction:) forControlEvents:UIControlEventTouchUpInside]; 

    [b setAction:action]; 
    [b setTarget:target]; 

    return b; 
} 

-(void)performBarButtonAction:(UIButton*)sender 
{ 
    [[self target] performSelector:self.action withObject:self]; 
} 
@end 
3

Esto también se puede hacer mediante programación, así (de curso):

primer lugar, crear una vista personalizada. Esta vista personalizada puede contener una imagen, botón o cualquier otra cosa que desee. La vista personalizada se puede hacer mediante programación o IB:

UIImage *customImage = [UIImage imageNamed:@"imageName"]; 
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, customImage.size.width, customImage.size.height)]; 
customView.backgroundColor = [UIColor colorWithPatternImage:customImage]; 

A continuación, crear una UIBarButtonItem e inicializar con la vista personalizada.

UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customView]; 

Ahora, sólo tiene que añadir el UIBarButton personalizado a la leftBarButtonItem:

self.navigationItem.leftBarButtonItem = customBarButtonItem; 
0

Una otra solución, creo que es más sencillo en el caso cuando se crea el botón programáticamente:

UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithImage:defaultImage 
              landscapeImagePhone:landscapeImage 
                  style:UIBarButtonItemStylePlain 
                  target:self 
                  action:@selector(someSelector)]; 
[button setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 
[button setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; 
1

Busca en esta sencilla solución.

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController 
{ 
barButtonItem.image = [UIImage imageNamed:@"navButton.png"]; 
barButtonItem.style = UIBarButtonItemStylePlain; 

[barButtonItem setBackgroundImage:[UIImage imageNamed:@"1x1.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES]; 
self.masterPopoverController = popoverController; 
} 

Aquí 1x1.png es una imagen png transparente de 1 píxel que se puede descargar desde el siguiente enlace

http://commons.wikimedia.org/wiki/File:1x1.png

+0

Una línea de soluciones de código definitivamente son buenas en mi libro –

+0

Puede usar [UIImage nuevo] en lugar de usar la imagen transparente. –

4
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"] 
                    style:UIBarButtonItemStylePlain 
                    target:self 
                    action:@selector(showMenu)]; 
Cuestiones relacionadas