¿Cómo agregar un botón derecho a un UINavigationController?


191

Estoy tratando de agregar un botón de actualización a la barra superior de un controlador de navegación sin éxito.

Aquí está el encabezado:

@interface PropertyViewController : UINavigationController {

}

Así es como estoy tratando de agregarlo:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain
                                          target:self action:@selector(refreshPropertyList:)];      
        self.navigationItem.rightBarButtonItem = anotherButton;
    }
    return self;
}

Respuestas:


362

Intenta hacerlo en viewDidLoad. En general, debe diferir todo lo que pueda hasta ese punto de todos modos, cuando se inicia un UIViewController, aún puede pasar bastante tiempo antes de que se muestre, no tiene sentido hacer el trabajo temprano y bloquear la memoria.

- (void)viewDidLoad {
  [super viewDidLoad];

  UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(refreshPropertyList:)];          
  self.navigationItem.rightBarButtonItem = anotherButton;
  // exclude the following in ARC projects...
  [anotherButton release];
}

En cuanto a por qué no funciona actualmente, no puedo decir con 100% de certeza sin ver más código, pero suceden muchas cosas entre init y la carga de la vista, y es posible que esté haciendo algo que hace que el elemento de navegación se restablezca en Entre.


45
Si está haciendo esto fuera de la subclase UINavigationController, se referiría de esta manera: someNavController.topLevelController.navigationItem.rightBarButtonItem = anotherButton
ransomweaver

2
Estaba implementando la solución sugerida y mi aplicación seguía fallando hasta que me di cuenta de que el nombre del método @selector tenía que terminar en dos puntos (:).
Stealth

10
Incluso dentro del método viewDidLoad de UINavigationContoller, tuve que llamarlo comoself.topViewController.navigationItem.leftBarButtonItem = nextButton;
Joseph

¡Gracias! @ Joseph, Tu aclaración me salvó. (y) :)
Prasanna

38

Intente agregar el botón al elemento de navegación del controlador de vista que se va a insertar en esta PropertyViewControllerclase que ha creado.

Es decir:

MainViewController *vc = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton addTarget:self action:@selector(showInfo) forControlEvents:UIControlEventTouchUpInside];
vc.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:infoButton] autorelease];

PropertyViewController *navController = [[PropertyViewController alloc] initWithRootViewController:vc];

Ahora, este infoButton que se ha creado programáticamente aparecerá en la barra de navegación. La idea es que el controlador de navegación recoja su información de visualización (título, botones, etc.) de la UIViewControllerque está a punto de mostrar. En realidad, no agrega botones y tal directamente al UINavigationController.


2
Establecer el rightBarButtonItem directamente en el UINavigationController no funcionó para mí (como lo propuso Louis Gerbarg anteriormente). ¡En lugar de configurar el elemento directamente en el UIViewController como Adem sugiere que funcionó!
leviatán

44
¡+1 para "Intente agregar el botón al elemento de navegación del controlador de vista que se va a presionar" !
Kjuly

25

Parece que algunas personas (como yo) pueden venir aquí buscando cómo agregar un botón de barra de navegación en el Creador de interfaces. La respuesta a continuación muestra cómo hacerlo.

Agregue un controlador de navegación a su guión gráfico

Seleccione su controlador de vista y luego en el menú Xcode elija Editor> Incrustar en> Controlador de navegación .

ingrese la descripción de la imagen aquí

Alternativamente, puede agregar uno UINavigationBardesde la Biblioteca de objetos.

Agregar un elemento de botón de barra

Arrastre a UIBarButtonItemdesde la Biblioteca de objetos a la barra de navegación superior.

ingrese la descripción de la imagen aquí

Debe tener un aspecto como este:

ingrese la descripción de la imagen aquí

Establecer los atributos

Puede hacer doble clic en "Elemento" para cambiar el texto a algo como "Actualizar", pero hay un icono real para Actualizar que puede usar. Simplemente seleccione los atributos para el inspector UIBarButtonItemy de artículo Sistema elija Actualizar .

ingrese la descripción de la imagen aquí

Eso le dará el icono de actualización predeterminado.

ingrese la descripción de la imagen aquí

Agregar una acción de IB

Controle el arrastre desde UIBarButtonItemal Controlador de vista para agregar un @IBAction.

class ViewController: UIViewController {

    @IBAction func refreshBarButtonItemTap(sender: UIBarButtonItem) {
        
        print("How refreshing!")
    }
    
}

Eso es.


Lo siento, no puedo entender lo que estás hablando. Intente hacer una nueva pregunta con una imagen que ilustre de qué está hablando. Luego agregue un enlace aquí.
Suragch

@Suragch, ¿cómo puedo hacer lo mismo con los archivos xib en lugar de los guiones gráficos? , gracias
Cristian Chaparro A.

@CristianChaparroA. Por lo general, los archivos xib son para vistas únicas y la barra de navegación (que aloja los elementos del botón de la barra) es para múltiples vistas. Nunca he usado un xib con elementos de botones de barra. Puede intentar hacer una nueva pregunta y luego vincularla aquí.
Suragch

14

Hay un botón de sistema predeterminado para "Actualizar":

- (void)viewDidLoad {
    [super viewDidLoad];

    UIBarButtonItem *refreshButton = [[[UIBarButtonItem alloc] 
                            initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
                            target:self action:@selector(refreshClicked:)] autorelease];
    self.navigationItem.rightBarButtonItem = refreshButton;

}

- (IBAction)refreshClicked:(id)sender {

}

11

Puedes usar esto:

C objetivo

UIBarButtonItem *rightSideOptionButton = [[UIBarButtonItem alloc] initWithTitle:@"Right" style:UIBarButtonItemStylePlain target:self action:@selector(rightSideOptionButtonClicked:)];          
self.navigationItem.rightBarButtonItem = rightSideOptionButton;

Rápido

let rightSideOptionButton = UIBarButtonItem()
rightSideOptionButton.title = "Right"
self.navigationItem.rightBarButtonItem = rightSideOptionButton

6
-(void) viewWillAppear:(BOOL)animated
{

    UIButton *btnRight = [UIButton buttonWithType:UIButtonTypeCustom];
    [btnRight setFrame:CGRectMake(0, 0, 30, 44)];
    [btnRight setImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal];
    [btnRight addTarget:self action:@selector(saveData) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barBtnRight = [[UIBarButtonItem alloc] initWithCustomView:btnRight];
    [barBtnRight setTintColor:[UIColor whiteColor]];
    [[[self tabBarController] navigationItem] setRightBarButtonItem:barBtnRight];

}

¿Alguien puede decirme si hay algún daño al hacerlo en ViewWillAppear en lugar de ViewDidLoad
Niranjan Molkeri

6

Para Swift 2:

self.title = "Your Title"

var homeButton : UIBarButtonItem = UIBarButtonItem(title: "LeftButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("yourMethod"))

var logButton : UIBarButtonItem = UIBarButtonItem(title: "RigthButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("yourMethod"))

self.navigationItem.leftBarButtonItem = homeButton
self.navigationItem.rightBarButtonItem = logButton

Recomendaría usar el nuevo selector swift2: #selector (classname.functionname)
Emptyless

5

Aquí está la solución en Swift (configure las opciones según sea necesario):

var optionButton = UIBarButtonItem()
optionButton.title = "Settings"
//optionButton.action = something (put your action here)
self.navigationItem.rightBarButtonItem = optionButton

4

¿Por qué son subclases UINavigationController? No hay necesidad de subclasificarlo si todo lo que necesita hacer es agregarle un botón.

Configure una jerarquía con un UINavigationControlleren la parte superior, y luego en el viewDidLoad:método del controlador de vista raíz : configure el botón y adjúntelo al elemento de navegación llamando

[[self navigationItem] setRightBarButtonItem:myBarButtonItem];

1
Esa es una buena pregunta. Lo que intento hacer es en realidad un patrón de diseño muy común, que es un controlador de pestañas básico con un controlador de navegación para cada pestaña. Si hay una mejor manera, estoy abierto a sugerencias. Tal vez debería hacer esa pregunta también.
Artilheiro


3

Swift 4:

override func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "tap me", style: .plain, target: self, action: #selector(onButtonTap))
}

@objc func onButtonTap() {
    print("you tapped me !?")
}

Simplemente use navigationItem.rightBarButtonItem si desea el botón del lado derecho
Ghanshyam Bagul

2
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 110, 50)];
view.backgroundColor = [UIColor clearColor];

UIButton *settingsButton =  [UIButton buttonWithType:UIButtonTypeCustom];
[settingsButton setImage:[UIImage imageNamed:@"settings_icon_png.png"] forState:UIControlStateNormal];
[settingsButton addTarget:self action:@selector(logOutClicked) forControlEvents:UIControlEventTouchUpInside];
[settingsButton setFrame:CGRectMake(40,5,32,32)];
[view addSubview:settingsButton];

UIButton *filterButton =  [UIButton buttonWithType:UIButtonTypeCustom];
[filterButton setImage:[UIImage imageNamed:@"filter.png"] forState:UIControlStateNormal];
[filterButton addTarget:self action:@selector(openActionSheet) forControlEvents:UIControlEventTouchUpInside];
[filterButton setFrame:CGRectMake(80,5,32,32)];
[view addSubview:filterButton];



self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:view];

2

Intenta esto, funciona para mí.

Barra de navegación y también imagen de fondo agregada al botón derecho.

 UIBarButtonItem *Savebtn=[[UIBarButtonItem alloc]initWithImage:[[UIImage    
 imageNamed:@"bt_save.png"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] 
 style:UIBarButtonItemStylePlain target:self action:@selector(SaveButtonClicked)];
 self.navigationItem.rightBarButtonItem=Savebtn;

0
    UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;

0
- (void)viewWillAppear:(BOOL)animated
{    
    [self setDetailViewNavigationBar];    
}
-(void)setDetailViewNavigationBar
{
    self.navigationController.navigationBar.tintColor = [UIColor purpleColor];
    [self setNavigationBarRightButton];
    [self setNavigationBarBackButton];    
}
-(void)setNavigationBarBackButton// using custom button 
{
   UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:@"  Back " style:UIBarButtonItemStylePlain target:self action:@selector(onClickLeftButton:)];          
   self.navigationItem.leftBarButtonItem = leftButton;    
}
- (void)onClickLeftButton:(id)sender 
{
   NSLog(@"onClickLeftButton");        
}
-(void)setNavigationBarRightButton
{

  UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(onClickrighttButton:)];          
self.navigationItem.rightBarButtonItem = anotherButton;   

}
- (void)onClickrighttButton:(id)sender 
{
   NSLog(@"onClickrighttButton");  
}

0
    self.navigationItem.rightBarButtonItem =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshData)];



}

-(void)refreshData{
    progressHud= [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
    [progressHud setLabelText:@"拼命加载中..."];
    [self loadNetwork];
}

0

Debes agregar tu barButtonItem en el - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animatedmétodo.


0

Simplemente copie y pegue este código Objective-C.

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self addRightBarButtonItem];
}
- (void) addRightBarButtonItem {
    UIButton *btnAddContact = [UIButton buttonWithType:UIButtonTypeContactAdd];
    [btnAddContact addTarget:self action:@selector(addCustomerPressed:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:btnAddContact];
    self.navigationItem.rightBarButtonItem = barButton;
}

#pragma mark - UIButton
- (IBAction)addCustomerPressed:(id)sender {
// Your right button pressed event
}

Estoy tratando de ayudar
Vivek

0

Este problema puede ocurrir si eliminamos el controlador de vista o intentamos agregar un nuevo controlador de vista dentro del generador de interfaces (main.storyboard). Para solucionar este problema, se requiere agregar "Elemento de navegación" dentro del nuevo controlador de vista. A veces sucede que creamos una nueva pantalla de controlador de vista y no se conecta al "Elemento de navegación" automáticamente.

  1. Vaya al main.storyboard.
  2. Seleccione esa nueva vista Controlador.
  3. Ir al esquema del documento.
  4. Verifique ver el contenido del controlador.
  5. Si el nuevo controlador de vista no tiene un elemento de navegación, copie el elemento de navegación del controlador de vista anterior y péguelo en el nuevo controlador de vista.
  6. guardar y limpiar el proyecto.

0

También puedes agregar varios botones usando rightBarButtonItems

-(void)viewDidLoad{

    UIBarButtonItem *button1 = [[UIBarButtonItem alloc] initWithTitle:@"button 1" style:UIBarButtonItemStylePlain target:self action:@selector(YOUR_METHOD1:)];
    UIBarButtonItem *button2 = [[UIBarButtonItem alloc] initWithTitle:@"button 2" style:UIBarButtonItemStylePlain target:self action:@selector(YOUR_METHOD2:)];

    self.navigationItem.rightBarButtonItems = @[button1, button2];
}

-1

@Artilheiro: Si es un proyecto basado en la navegación, puede crear BaseViewController. Todas las demás vistas heredarán esta BaseView. En BaseView, puede definir métodos genéricos para agregar el botón derecho o cambiar el texto del botón izquierdo.

ex:

@interface BaseController: UIViewController {

} - (vacío) setBackButtonCaption: (NSString *) caption;

(nulo) setRightButtonCaption: (NSString *) caption selectot: (SEL) selector;

@end // En BaseView.M

(nulo) setBackButtonCaption: (NSString *) caption {

UIBarButtonItem *backButton =[[UIBarButtonItem alloc] init];

backButton.title= caption;
self.navigationItem.backBarButtonItem = backButton;
[backButton release];

} - (vacío) setRightButtonCaption: (NSString *) caption selectot: (SEL) selector {

  UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] init];
rightButton.title = caption;

rightButton.target= self;

[rightButton setAction:selector];

self.navigationItem.rightBarButtonItem= rightButton;

[rightButton release];

}

Y ahora, en cualquier vista personalizada, implemente esta vista base, llame a los métodos:

@interface LoginView: BaseController {

En algún método, llame al método base como:

SEL sel = @selector (switchToForgotPIN);

[super setRightButtonCaption: @ "Olvidé mi PIN" selectot: sel];

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.