iphone - restaure - Botón de retroceso personalizado en UINavigationController
reparar boton home iphone 5 (10)
Para una aplicación que estoy desarrollando, necesito mostrar un botón de retroceso personalizado en una barra de navegación. Tengo el botón activo como una imagen PNG, y estoy escribiendo este código:
- (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 presiono este controlador de vista, el botón personalizado no aparece, y en su lugar obtengo el botón de retroceso estándar con el título de este controlador de vista en el interior.
Cosas que ya probé:
- Verifique que el botón
backButton
se haya creado correctamente, agregándolo a la jerarquía de vistas. Se muestra correctamente. - En el mismo método, cambié la propiedad del
title
del elemento denavigationItem
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 botón de retroceso con un UINavigationController
?
¿No es la solución más simple solo para diseñarlo desde 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) }
Comenzando con iOS 5, esto es simple:
[[UIBarButtonItem appearance]
setBackButtonBackgroundImage:[UIImage imageNamed:@"back_button.png"]
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
Puede colocar eso en el delegado de su aplicación y establecerá la imagen de fondo en todos los botones de retroceso en la aplicación (para ese estado de control y métricas de barra, por supuesto).
Como @pgb sugirió, puede usar leftBarButtonItem en lugar del elemento del botón Atrás. Y para eliminar el elemento predeterminado del botón Atrás, configúrelo como nulo como sigue;
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
Confusamente, backBarButtonItem
no es lo que estás buscando.
Solo controla el título en el botón Atrás para el siguiente controlador de vista. Lo que desea es establecer el leftBarButtonItem
en su botón de retroceso personalizado.
Estoy reenviando mi solución desde https://.com/a/16831482/171933 :
Creo 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
en todos sus controladores de vista o en una clase de controlador de vista base personalizada que otros controladores de vista heredan e implementan el método viewWillAppear:
:
- (void)viewWillAppear:(BOOL)animated
{
[self setUpImageBackButton];
}
Eso es todo. Ahora tienes un botón de retroceso de imagen en todas partes. Sin una frontera. ¡Disfrutar!
La propiedad backBarButtonItem
funciona según lo previsto, pero siempre agregará su forma y color de botón estándar según el color del tinte de la barra de navegación.
Puede personalizar el texto, pero no reemplazar la imagen.
Una solución alternativa, como sugirió Andrew Pouliot, es usar leftBarButtonItem
en leftBarButtonItem
lugar, pero en lugar de eso, me quedé con el botón estándar.
La respuesta de Johannes Fahrenkrug funciona, pero la imagen trasera aparece en una posición muy cableada.
Aquí encontré una mejor manera de colocar la imagen en el lugar correcto:
Asegúrate de que tienes una imagen de fondo con un tamaño de 24x24 (@ 1x), lo llamo de backImage
Ejecuta el siguiente código cuando inicies tu aplicación
UINavigationBar.appearance().barTintColor = nil
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics: .Default)
No creo que el propio ViewController deba saber nada acerca de su botón de retroceso. De acuerdo con OOP, esto es responsabilidad del containerViewController en el que se inserta el controlador de vista, por ejemplo, UINavigationController.
Subclase su NavigationController y sobrecargue en su método superClass como este:
@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
Simplemente cree un UIBarButtonItem
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;
Vea esta respuesta aquí: Cómo crear backBarButtomItem con vista personalizada para un UINavigationController
Solo necesita establecer la propiedad backBarButtonItem
en el navigationController antes de presionar viewController. La configuración de la propiedad backBarButtonItem
en el método viewDidLoad de viewDidLoad
(por ejemplo) no funciona.