UINavigationController "botão voltar" texto personalizado?

147

O "botão voltar" de a UINavigationControllerpor padrão mostra o título da última exibição na pilha. Existe uma maneira de ter texto personalizado no botão Voltar?

Ali Shafai
fonte
1
Este trabalho para mimself.navigationController.navigationBar.topItem.title = @"Custom text";
huync

Respostas:

342

A partir deste link :

self.navigationItem.backBarButtonItem =
   [[UIBarButtonItem alloc] initWithTitle:@"Custom Title"
            style:UIBarButtonItemStylePlain
           target:nil
           action:nil];

Como Tyler disse nos comentários:

não faça isso no controlador de exibição visível, mas no controlador de exibição que você veria se apertasse o botão Voltar

rédea
fonte
4
Você deve releaseo UIBarButtonItem.
Mehrdad Afshari 17/09/09
217
Observe também que você precisa fazer isso no controlador de exibição um nível acima da pilha. Em outras palavras, não faça isso no controlador de exibição visível, mas no controlador de exibição que você veria se apertasse o botão Voltar.
Tyler
6
Apenas para esclarecer o comentário de Tyler, porque eu não entendi isso no começo: Configurando o backBarButtonItem em um modo de exibição de controladores navigationItem está configurando o botão que será exibido para retornar a esse controlador de modo de exibição. Observe também que, embora não exista um estilo de botão para o botão de seta, esse botão terá o estilo da seta de qualquer maneira. Eu usei UIBarButtonItemStylePlain e ainda recebo o estilo do botão de seta.
91111 Jon Steinmetz
3
Sugestão: em vez de assumir o estilo, passe o estilo definido atualmente. No código desta resposta, substitua UIBarButtonItemStyleBorderedcom uma chamada para a propriedade self.navigationItem.backBarButtonItem.style. Documentação: developer.apple.com/library/ios/documentation/uikit/reference/…
Basil Bourque
1
Observe que, no ARC, você deve excluir a chamada de autorelease. para que você tenha self.navigationItem.backBarButtonItem = [[UIBarButtonItem alocado] initWithTitle: @ estilo "Título personalizado": UIBarButtonItemStyleBordered target: nil action: nil];
precisa saber é o seguinte
43

Você pode definir o texto no Interface Builder:

Selecione o item de navegação do ViewController ao qual o botão Voltar retornaria:

insira a descrição da imagem aqui

No inspetor de atributos do painel de utilitários, insira sua etiqueta para o Botão Voltar:

insira a descrição da imagem aqui

Eu preferiria essa abordagem ao invés de definir o título no código, como na resposta aceita.

Observe também que você precisa fazer isso no controlador de exibição um nível acima da pilha. Em outras palavras, não faça isso no controlador de exibição visível, mas no controlador de exibição que você veria se apertasse o botão Voltar.
--Tyler

Petr Peller
fonte
Esta é a melhor resposta que encontrei até agora.
Ayan Sengupta
2
Para ficar claro, isso precisa ser definido no item de navegação do controlador de exibição, não no próprio inspetor de atributos do controlador de exibição.
Patrick Leia
Esta é a melhor resposta que encontrei.
precisa saber é o seguinte
Esta é a melhor resposta
Alex Brown
2
A partir do Xcode 6.1.1 e em execução no iOS 7, parece que o título da visualização anterior ainda substituirá o título do botão voltar definido aqui. Se o título da visualização anterior contiver mais do que o limite de 11 caracteres, o botão Voltar da visualização seguinte dirá simplesmente "Voltar". Não há como contorná-lo, exceto para criar um novo item da barra de navegação do zero, como mostrado na resposta mais votada aqui.
ray
22

Eu uso isso:

// In the current view controller, not the one that is one level up in the stack
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.navigationBar.backItem.title = @"Custom text";
}
Trang
fonte
Esta quase funciona para mim, mas quando clico no botão voltar, o texto é alterado voltar para o título do pai para a duração da animação :-(
Danny Tuppeny
3
Isso altera o título do botão Voltar do controlador na pilha. Não altera o título do botão Voltar do controlador atualmente exibido. Pior ainda: altera o título do controlador anterior ao controlador anterior!
leviathan
Como observado por outros comentaristas, esse método é um pouco insustentável. Eu não recomendaria fazer isso, pois não é exatamente como a API pretende que você a use. Você pode se preparar para erros difíceis no futuro!
RickDT
11

Encontrei uma solução útil para isso, basta definir o título do controlador antes de colocar outro controlador na pilha, desta forma:

self.navigationItem.title = @"Replacement Title";
[self.navigationController pushViewController:newCtrl animated:YES];

Em seguida, certifique-se de definir o título original viewWillAppear, assim:

-(void)viewWillAppear:(BOOL)animated
{
  ...
  self.navigationItem.title = @"Original Title";
  ...
}

Isso funciona porque o comportamento padrão UINavigationControllerao construir o botão voltar durante uma operação de envio é usar o título do controlador anterior.

Aubrey Goodman
fonte
1
O problema com isso é que o título muda na exibição antiga, pois é animada e parece um pouco irritante. Nenhuma das soluções dadas aqui parecem funcionar como você gostaria :-(
Danny Tuppeny
1
Isso é perfeito na minha situação, porque eu não mostro a NavBar na tela anterior e só quero remover o titleLabel do botão voltar da nova tela e ter apenas a seta do iOS7. Portanto, posso apenas definir um literal NSString vazio para o título.
siburb
empurrando o controlador de exibição gera a exceção ao tocar na parte traseira
Sumit
7

O título do botão Voltar é padronizado com o título da visualização anterior, portanto, um truque rápido que eu uso é colocar o seguinte código no arquivo .m da visualização anterior.

-(void)viewWillAppear:(BOOL)animated {

    // Set title
    self.navigationItem.title=@"Original Title";
}

-(void)viewWillDisappear:(BOOL)animated {

    // Set title
    self.navigationItem.title=@"Back";
}
AddisDev
fonte
Isso funciona muito bem em muitos casos e é bem simples ... apenas a observação é que a substituição de qualquer um desses métodos requer que a implementação do super seja chamada em algum momento do novo método.
Izk
2
Com esse método, notamos que o título da visualização principal foi alterado para 'Voltar' antes que a animação push aconteça. (E, sorta suga, que, se você mover este para o método viewDidDisappear, você verá o interruptor acontecendo após o impulso ..)
James Boutcher
Eu amo esse método, mas o problema que enfrento é que o "Título original" é definido corretamente, mas ele vem com reticências se for maior que "Voltar", o que deve ser porque, uma vez que a exibição ainda não está na hierarquia da exibição , não retransmitirá a exibição do título. O problema descrito por @JamesBoutcher acima é imperceptível para mim devido à rápida velocidade inicial da animação. Na verdade, acabei de perceber que o problema que enfrento é especialmente perceptível devido à animação de final lento, que é quando esse problema é proeminente.
trss
Embora a resposta em stackoverflow.com/questions/1441699/… pareça mais personalizada do que o necessário, é a maneira documentada e mais importante parece estar mais alinhada com a nossa intenção.
trss
6

no seu método init, adicione o seguinte código:

- (id)initWithStyle:(UITableViewStyle)style {
    if(self = [super init]) {

        //...

        UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" 
                                             style:UIBarButtonItemStylePlain 
                                            target:self 
                                            action:@selector(goBack)];
        self.navigationItem.leftBarButtonItem = customBackButton;
        [customBackButton release];

        //...
    }
    return self;
}

adicione um método simples, para permitir que o viewcontroller seja descartado:

-(void)goBack {
    [self.navigationController popViewControllerAnimated:YES];  
}
valvoline
fonte
3

Adicione o seguinte código em viewDidLoad ou loadView

self.navigationController.navigationBar.topItem.title = @"Custom text";

Eu testei no iPhone e iPad com iOS 9

sozinho
fonte
Deve ser self.navigationController? .NavigationBar.backItem? .Title = "Texto personalizado"
Peacemoon
1
A única diferença que eu precisava era do encadeamento opcional nas propriedades navigationControllere topItem, por exemplo:self.navigationController?.navigationBar.topItem?.title = "Custom Text"
Bulwinkel 8/16
2

Adicionando a resposta da rédea. Observe nos documentos da Apple que a declaração de backBarButtonItem é esta:

@property(nonatomic, retain) UIBarButtonItem *backBarButtonItem

Portanto, a resposta da rédea vazará memória porque o setter sintetizado será retaina instância em que você a passa, que nunca é liberada explicitamente. Você pode remediar isso usandoautorelease

 self.navigationItem.backBarButtonItem = 
      [[[UIBarButtonItem alloc] initWithTitle:@"Custom Title" 
         style:UIBarButtonItemStyleBordered
         target:nil
         action:nil] autorelease];  //<-- autoreleased

Ou você pode apontar uma variável para a instância para liberá-la explicitamente mais tarde:

UIBarButtonItem* item = ...
self.navigationItem.backBarButtonItem = item;
[item release];

Espero que isto ajude!

Eric Goldberg
fonte
Nota estes dias, com ARC, você não precisa se preocupar com o disparo automático (e de fato o compilador de erro se você tentar autorelease em um projeto ARC-habilitado)
Eric Goldberg
2
- (void)viewDidLoad {
  [super viewDidLoad];

  UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
  self.navigationItem.backBarButtonItem = backButton;
  [backButton release];
}
LCANT
fonte
2

Eu descobri algo interessante. Se você subclassificar UINavigationControllere substituir o pushViewController:animated:método e fizer algo assim: (lembre-se de que estou usando o ARC)

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] 
 initWithTitle: @"Back" 
 style: UIBarButtonItemStyleBordered
 target: nil action: nil];

viewController.navigationItem.backBarButtonItem = backButton;

[super pushViewController:viewController animated:animated];

Então, para todos os ViewControllersque são pressionados com o seu controlador de navegação, o botão "Voltar" aparecerá automaticamente. Se você deseja alterar o texto de determinados controladores de exibição, pode tentar converter o viewcontroller para uma determinada classe ou seu próprio protocolo personalizado (que o seu viewcontroller herda do qual poderia ter um método comobackButtonText ou algo parvo), que pode fornecer a você certas informações no controlador de exibição que estão chegando para que você possa personalizar o texto do botão Voltar. Agora, o texto do botão Voltar é tratado em um local que deve ser de responsabilidade exclusiva. Eu tenho que admitir que criar um novo botão para alterar o texto é uma porcaria, mas tudo bem.

Alguém pode pensar em uma razão pela qual não fazê-lo assim? Pelo menos você não precisa mexer nos títulos dos controladores de visualização ou precisa se lembrar de criar um novo botão Voltar antes de pressionar o controlador de visualização no controlador de navegação.

Dandré
fonte
0

A resposta da rédea funciona bem.

Observe que, se você pressionar mais de um controlador de exibição, o título do botão Voltar alterado será exibido para cada um deles, o que pode não ser o desejado.

Nesse caso, você precisará criar o UIBarButtonItem personalizado sempre que pressionar um controlador de exibição.

Além disso, certifique-se de fazê-lo antes de pressionar o controlador de exibição, caso contrário, você verá um soluço na tela conforme o título for alterado.

homem do norte
fonte
0

Expandindo a sugestão de Aubrey, você pode fazer isso no controlador de exibição filho:

crie duas variáveis ​​para armazenar os valores antigos do navigationItem.title do pai e o navigationItem do pai

UINavigationItem* oldItem;
NSString* oldTitle;

em viewDidLoad, adicione o seguinte:

oldItem = self.navigationController.navigationBar.topItem;  
oldTitle = oldItem.title;  
[oldItem setTitle: @"Back"];  

em viewWillDisappear, adicione o seguinte:

[oldItem setTitle: oldTitle];  
oldTitle = nil;  // do this if you have retained oldTitle
oldItem = nil;   // do this if you have retained oldItem

Não é perfeito. Você verá o título da visualização pai mudar à medida que o novo controlador é animado. MAS isso atinge o objetivo de rotular o botão voltar personalizado e mantê-lo em forma de um botão voltar padrão.

FingerTipFun
fonte
0

Coloque isso em você viewDidLoad, espero que resulte no que você está procurando

UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" 
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarButtonItem;
[backBarButtonItem release];
Ravi_Parmar
fonte
0

Se você deseja definir o título no controlador ARRIVING (às vezes mais lógico ..) no swift 3, faça:

func setBackButtonNavBar(title: String, delay: Double){

    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in

        if let navBar = self.navigationController?.navigationBar{
            navBar.backItem?.title = title
        }
    })

}

no próximo controlador:

override func viewDidLoad() {
    super.viewDidLoad()
    self.setBackButtonNavBar(title: "back", delay: 0.3)
}

geralmente coloco self.setBackButtonNavBar em uma extensão do controlador.

ingconti
fonte
0

Sei que essa é uma pergunta antiga e as respostas estão atualizadas!

A maneira mais fácil é fazer isso no ViewController pai:

ou seja, aquele que leva você ao próximo controlador de exibição.

self.navigationItem.backBarButtonItem  = UIBarButtonItem(title: "Custom text here", style: .plain, target: nil, action: nil)
madeny
fonte
-1

Fazendo isso no código, remova o estilo do botão Voltar do UINavigationConroller. Se você adicionar um Item de Navegação em cada uma das suas visualizações, poderá definir o título do botão de retorno no StoryBoard.

gjseminario
fonte