2010-08-17 37 views
17

Para una aplicación que estoy desarrollando, necesito mostrar un botón Atrás personalizado en una barra de navegación. Tengo el activo botón como una imagen PNG, y estoy escribiendo este código:Botón Atrás personalizado en UINavigationController

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
    backButton.frame = CGRectMake(0, 0, 79, 29.0); 
    [backButton setImage:[UIImage imageNamed:@"button_back.png"] forState:UIControlStateNormal]; 
    self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease]; 

}

Cuando pulso este controlador de vista, el botón personalizado no aparece, y en su lugar me da la botón de retroceso estándar con el título de este controlador de vista dentro.

cosas que ya probado:

  1. verificación Doblado de que el botón backButton se crea correctamente, añadiéndolo a la jerarquía de vistas. Se muestra correctamente.
  2. En el mismo método, cambió la propiedad title del navigationItem y confirmó que cambia (como se esperaba) el contenido de mi botón Atrás.

¿Alguien puede detectar lo que estoy haciendo mal? ¿Alguien logró usar una imagen personalizada como el botón Atrás con UINavigationController?

Respuesta

5

La propiedad backBarButtonItem funciona según lo previsto, pero siempre agregará su forma y color de botón estándar en función del color del tinte de la barra de navegación.

Puede personalizar el texto, pero no reemplazar la imagen.

Una solución, como sugirió Andrew Pouliot, es usar leftBarButtonItem en su lugar, pero me quedé con el botón estándar en su lugar.

3

Confusamente backBarButtonItem no es lo que estás buscando.

Simplemente controla el título en el botón Atrás para el siguiente controlador de vista. Lo que desea es configurar el leftBarButtonItem en su botón de retroceso personalizado.

+3

Creo que quiero 'backBarButtonItem'. Lo que quiero controlar es cómo se verá el botón Atrás cuando se empuje el 'UIViewController' en la pila' UINavigationController'. De hecho, los cambios menores en el trabajo 'backBarButtonItem' funcionan como se esperaba, es solo la vista personalizada que no se pega. – pgb

+1

La propiedad backBarButtonItem funciona. Solo tengo que configurarlo en el momento correcto. – SundayMonday

0

Simplemente cree un UIBarButtonItem en lugar de un UIButton incrustado en UIBarButtonItem. ¡Funciona bien!

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"button_back.png"] style:UIBarButtonItemStyleBordered target:nil action:nil]; 

self.navigationItem.backBarButtonItem = backButton; 
+1

Esto no funciona. La imagen de fondo del botón de retroceso aún se muestra (a menos que la imagen que utiliza sea más grande que la imagen predeterminada del botón Atrás) – probablyCorey

+0

http: // stackoverflow.com/questions/526520/how-to-create-backbarbuttomitem-with-custom-view-for-a-uinavigationcontroller/7184426 # 7184426 – SundayMonday

18

A partir de iOS 5, esto es simple:

[[UIBarButtonItem appearance] 
      setBackButtonBackgroundImage:[UIImage imageNamed:@"back_button.png"] 
      forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 

se puede colocar de que en delegado de la aplicación y de esta forma se establece la imagen de fondo a todos los botones atrás en la aplicación (por ese estado de control y las métricas de barras , por supuesto).

+27

Esto no oculta el título del botón – user366584

+5

¿Hay alguna forma de ocultar el título del botón? – ArdenDev

+1

este ancho de fondo depende de la longitud del título. La imagen se estirará según la longitud del título. – Add080bbA

13

Estoy volver a colocar mi solución de https://stackoverflow.com/a/16831482/171933:

que crear una categoría simple en UIViewController:

UIViewController + ImageBackButton.h

#import <UIKit/UIKit.h> 

@interface UIViewController (ImageBackButton) 

- (void)setUpImageBackButton; 

@end 

UIViewController + ImageBackButton.m

#import "UIViewController+ImageBackButton.h" 

@implementation UIViewController (ImageBackButton) 

- (void)setUpImageBackButton 
{ 
    UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 34, 26)]; 
    [backButton setBackgroundImage:[UIImage imageNamed:@"back_arrow.png"] forState:UIControlStateNormal]; 
    UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton]; 
    [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside]; 
    self.navigationItem.leftBarButtonItem = barBackButtonItem; 
    self.navigationItem.hidesBackButton = YES; 
} 

- (void)popCurrentViewController 
{ 
    [self.navigationController popViewControllerAnimated:YES]; 
} 

@end 

Ahora todo lo que tiene que hacer es #import UIViewController+ImageBackButton.h, ya sea en todos sus controladores de vista o en una vista base personalizado clase controlador que sus otros controladores de vista heredan de e implementan la viewWillAppear: método:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [self setUpImageBackButton]; 
} 

eso es todo. Ahora tiene un botón de retroceso de imagen en todas partes. Sin un borde ¡Disfrutar!

+0

[backButton addTarget: self.navigationController action: @selector (popViewControllerAnimated :) forControlEvents: UIControlEventTouchUpInside]; no proporciona el argumento 'animado' y no está definido. es mejor agregar un método que explícitamente proporcione el argumento 'animado' –

+0

@OrArbel Gracias, tienes razón. Funciona tal como es, pero es más limpio llamarlo explícitamente. He editado el código :) –

+1

Esto está bien pero deshabilitará el deslizamiento para retroceder si oculta el botón Atrás. Entonces IMO pierde más de lo que gana. – AppHandwerker

3

¿No es la solución más simple diseñarla solo con su guión gráfico con la imagen o los colores que desee y simplemente arrastrar una nueva acción a su controlador?

Código Swift

@IBAction func backButton(sender: AnyObject) { 
    self.navigationController?.popViewControllerAnimated(true) 
} 
+3

¡SO es tan genial! Hice esta pregunta en 2010, y ahora recibo una respuesta con un código Swift de ejemplo, y sugiero el uso de Storyboards :) – pgb

1

No creo que sí ViewController debe saber nada sobre su botón de retroceso De acuerdo con la POO esto es responsabilidad de containerViewController en el que se inserta el controlador de vista , por ejemplo UINavigationController.

Subclase su NavigationController y la sobrecarga en el mismo método de una clase como esta: La respuesta de las obras

@implementation STONavigationController 

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
    [super pushViewController:viewController animated:animated]; 
    if ([self.viewControllers indexOfObject:viewController] != NSNotFound && 
     [self.viewControllers indexOfObject:viewController] > 0){ 
     UIImage *img = [UIImage imageNamed:@"back-1"]; 
     UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, img.size.width * 2, img.size.height * 2)]; 
     [backButton setBackgroundImage:img forState:UIControlStateNormal]; 
     UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton]; 
     [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside]; 
     viewController.navigationItem.leftBarButtonItem = barBackButtonItem; 
     viewController.navigationItem.hidesBackButton = YES; 
    } 
} 

- (void)popCurrentViewController 
{ 
    [self popViewControllerAnimated:YES]; 
} 

@end 
1

Johannes Fahrenkrug, pero la imagen de nuevo aparecerían en una posición muy por cable.

Aquí he encontrado una mejor manera de posicionar la imagen en el lugar correcto:

Asegúrese de que tiene una imagen con tamaño de 24x24 (@ 1x), lo llamo backImage

Ejecutar el siguiente código cuando su aplicación Lanzamiento

UINavigationBar.appearance().barTintColor = nil 
UINavigationBar.appearance().backIndicatorImage = backImage 
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage 
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics: .Default) 
+0

EstablecíBackButtonTitlePositionAdjustment en didFinishLaunchingWithOptions y en algunas pantallas puedo ver el título del botón retro animando fuera de la pantalla: / –

0

Como @pgb sugirió que puede utilizar en lugar de leftBarButtonItem elemento botón de retroceso. Y para eliminar el ítem predeterminado del botón Atrás, configúrelo a cero de la siguiente manera;

navigationController?.navigationBar.backIndicatorImage = nil 
navigationController?.navigationBar.backIndicatorTransitionMaskImage = nil 

let button = UIButton.init(type: .custom) 
button.imageView?.contentMode = UIViewContentMode.scaleAspectFit 
button.setImage(UIImage.init(named: "top_back"), for: UIControlState.normal) 
button.frame = CGRect.init(x: 0, y: 0, width: 75, height: 50) 
button.addTarget(self, action: #selector(handleBackButton), for: .touchUpInside) 

let barButton = UIBarButtonItem.init(customView: button) 
self.navigationItem.leftBarButtonItem = barButton 
Cuestiones relacionadas