Como adicionar um botão direito a um UINavigationController?

191

Estou tentando adicionar um botão de atualização à barra superior de um controlador de navegação sem êxito.

Aqui está o cabeçalho:

@interface PropertyViewController : UINavigationController {

}

Aqui está como eu estou tentando adicioná-lo:

- (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;
}
Artilheiro
fonte

Respostas:

362

Tente fazer isso em viewDidLoad. Geralmente, você deve adiar tudo o que puder até esse ponto, quando um UIViewController é iniciado, ainda pode demorar um pouco antes de ser exibido, não faz sentido trabalhar cedo e vincular a memória.

- (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];
}

Quanto ao motivo de ele não estar funcionando atualmente, não posso dizer com 100% de certeza sem ver mais código, mas muitas coisas acontecem entre o init e o carregamento da visualização, e você pode estar fazendo algo que faz com que o navigationItem seja redefinido em entre.

Louis Gerbarg
fonte
45
Se você estiver fazendo isso fora da subclasse UINavigationController, consulte-o assim: someNavController.topLevelController.navigationItem.rightBarButtonItem = anotherButton
ransomweaver
2
Eu estava implementando a solução sugerida e meu aplicativo continuou travando até perceber que o nome do método @selector deve terminar em dois-pontos (:).
Discrição
10
Mesmo dentro do método viewDidLoad um UINavigationContoller, eu tive que chamá-lo assimself.topViewController.navigationItem.leftBarButtonItem = nextButton;
Joseph
Obrigado! @ Joseph, seu esclarecimento me salvou. (y) :)
Prasanna
38

Tente adicionar o botão ao item de navegação do controlador de exibição que será empurrado para este PropertyViewController classe que você criou.

Isso é:

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];

Agora, esse botão de informações que foi criado programaticamente será exibido na barra de navegação. A idéia é que o controlador de navegação pegue suas informações de exibição (título, botões, etc.) das UIViewControllerque está prestes a exibir. Na verdade, você não adiciona botões e outros diretamente ao UINavigationController.

Adão
fonte
2
Definir o rightBarButtonItem diretamente no UINavigationController não funcionou para mim (como proposto por Louis Gerbarg acima). Em vez disso, defina o item diretamente no UIViewController, como Adem sugere, funcionou!
leviatã
4
+1 em "Tente adicionar o botão ao item de navegação do controlador de exibição que será pressionado" !
Kjuly
25

Parece que algumas pessoas (como eu) podem vir aqui procurando como adicionar um botão da barra de navegação no Interface Builder. A resposta abaixo mostra como fazê-lo.

Adicione um controlador de navegação ao seu Storyboard

Selecione seu View Controller e, no menu Xcode, escolha Editor> Incorporar> Navegador .

insira a descrição da imagem aqui

Como alternativa, você pode adicionar um UINavigationBarda Biblioteca de Objetos.

Adicionar um item de botão de barra

Arraste a UIBarButtonItemda Biblioteca de objetos para a barra de navegação superior.

insira a descrição da imagem aqui

Deve ficar assim:

insira a descrição da imagem aqui

Defina os atributos

Você pode clicar duas vezes em "Item" para alterar o texto para algo como "Atualizar", mas existe um ícone real para a Atualização que você pode usar. Basta selecionar o Inspetor de atributos para o itemUIBarButtonItem e, em Sistema, selecione Atualizar .

insira a descrição da imagem aqui

Isso fornecerá o ícone de atualização padrão.

insira a descrição da imagem aqui

Adicionar uma ação de IB

Arraste a tecla Control UIBarButtonItempara o View Controller para adicionar uma @IBAction.

class ViewController: UIViewController {

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

É isso aí.

Suragch
fonte
Desculpe, não consigo entender bem o que você está falando. Tente fazer uma nova pergunta com uma imagem que ilustra o que você está falando. Em seguida, adicione um link para ele aqui.
Suragch 02/03
@ Suragch, como posso fazer as mesmas coisas com arquivos xib em vez de storyboards? , obrigado
Cristian Chaparro A.
@CristianChaparroA. Geralmente, os arquivos xib são para visualizações únicas e a barra de navegação (que hospeda os itens do botão de barra) é para várias visualizações. Eu nunca usei um xib com itens de botão de barra. Você pode tentar fazer uma nova pergunta e criar um link para ela aqui.
Suragch 28/03
14

Há um botão de sistema padrão para "Atualizar":

- (void)viewDidLoad {
    [super viewDidLoad];

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

}

- (IBAction)refreshClicked:(id)sender {

}
Manni
fonte
11

Você pode usar isso:

Objetivo-C

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
Vandit Mehta
fonte
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];

}
Gaurav Gilani
fonte
Alguém pode me dizer que há algum mal em fazê-lo em ViewWillAppear em vez de ViewDidLoad
Niranjan Molkeri
6

Para o rápido 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
fandro
fonte
Eu recomendaria usar o novo seletor swift2: #selector (classname.functionname)
Emptyless
5

Aqui está a solução no Swift (defina as opções conforme necessário):

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

Por que você é subclasse UINavigationController? Não há necessidade de subclassificar se tudo o que você precisa fazer é adicionar um botão a ele.

Configure uma hierarquia com a UINavigationControllerna parte superior e, em seguida, no viewDidLoad:método do controlador de visualização raiz : configure o botão e anexe-o ao item de navegação chamando

[[self navigationItem] setRightBarButtonItem:myBarButtonItem];
Jasarien
fonte
1
Essa é uma boa pergunta. O que estou tentando fazer é realmente um padrão de design muito comum, que é um controlador de guia básico com um controlador de navegação para cada guia. Se houver uma maneira melhor, estou aberto a sugestões. Talvez eu deva fazer essa pergunta também.
Artilheiro
4

Podes tentar

self.navigationBar.topItem.rightBarButtonItem = anotherButton;
user2999133
fonte
Trabalhou como um encanto :)
Saurabh Bhatia
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 !?")
}
ergunkocak
fonte
Basta usar navigationItem.rightBarButtonItem se você quiser botão do lado direito
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];
Sandeep
fonte
2

Tente isso. Funciona para mim.

Barra de navegação e também adicionou imagem de fundo ao botão direito.

 UIBarButtonItem *Savebtn=[[UIBarButtonItem alloc]initWithImage:[[UIImage    
 imageNamed:@"bt_save.png"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] 
 style:UIBarButtonItemStylePlain target:self action:@selector(SaveButtonClicked)];
 self.navigationItem.rightBarButtonItem=Savebtn;
Jaywant Khedkar
fonte
0
    UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;
Mahesh Aswathanarayana
fonte
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");  
}
tv.ashvin
fonte
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];
}
Gank
fonte
0

Você deve adicionar seu barButtonItem no - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animatedmétodo

Retik
fonte
0

Basta copiar e colar 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
}
Vivek
fonte
Eu estou tentando ajudar #
217 Vivek
0

Esse problema pode ocorrer se excluirmos o controlador de exibição ou tentarmos adicionar um novo controlador de exibição dentro do construtor de interface (main.storyboard). Para corrigir esse problema, é necessário adicionar "Item de Navegação" dentro do novo controlador de exibição. Às vezes, criamos uma nova tela do controlador de exibição e ela não se conecta ao "Item de navegação" automaticamente.

  1. Vá para o main.storyboard.
  2. Selecione essa nova visualização Controller.
  3. Vá para o esboço do documento.
  4. Verifique a visualização do conteúdo do controlador.
  5. Se o novo view controller não tiver um item de Navegação, copie o item Navigation do anterior View Controller e cole-o no novo view controller.
  6. salve e limpe o projeto.
NilamK
fonte
0

Além disso, você pode adicionar vários botões 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];
}
yoAlex5
fonte
-1

@Artilheiro: Se é um projeto baseado em navegação, você pode criar o BaseViewController. Todas as outras visualizações herdarão esse BaseView. No BaseView, você pode definir métodos genéricos para adicionar o botão direito ou alterar o texto do botão esquerdo.

ex:

@interface BaseController: UIViewController {

} - (void) setBackButtonCaption: (NSString *) legenda;

(void) setRightButtonCaption: (NSString *) caption selectot: (SEL) seletor;

@end // No BaseView.M

(void) setBackButtonCaption: (NSString *) legenda {

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

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

} - (void) setRightButtonCaption: (NSString *) legenda selectot: (SEL) seletor {

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

rightButton.target= self;

[rightButton setAction:selector];

self.navigationItem.rightBarButtonItem= rightButton;

[rightButton release];

}

E agora, em qualquer visualização personalizada, implemente essa visualização base, chame os métodos:

@interface LoginView: BaseController {

Em algum método, chame o método base como:

SEL sel = @seletor (switchToForgotPIN);

[super setRightButtonCaption: @ "Esqueceu o PIN" selectot: sel];

iPhoneDev
fonte