Removendo o texto do título de um iOS UIBarButtonItem


198

O que eu queria fazer era remover o texto do botão 'Voltar' de a UIBarButtonItem, deixando apenas a divisa azul na barra de navegação. Lembre-se de que estou desenvolvendo para o iOS 7. Tentei vários métodos, incluindo, entre outros:

Este é o método de imagem que eu não gostei (a imagem parecia fora de lugar):

UIBarButtonItem *barBtnItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"iOS7BackButton"] style:UIBarButtonItemStylePlain target:self action:@selector(goToPrevious:)];
self.navigationItem.leftBarButtonItem = barBtnItem;

Outro método que tentei foi este, que simplesmente não funcionou (nada foi exibido):

UIBarButtonItem *barBtn = [[UIBarButtonItem alloc]init];
barBtn.title=@"";
self.navigationItem.leftBarButtonItem=barBtn;

O que eu queria alcançar era algo como os botões voltar encontrados no aplicativo iOS 7 Music, que apresentavam apenas uma única divisa.

Obrigado.



Por que você não imagina qual é a sua exigência? E consulte-o em leftBarButtonItem.
Vishal Sharma

A razão pela qual não usei o método de imagem é 1. É muito difícil obter uma imagem perfeita do botão Voltar e 2. Haverá algum tipo de desalinhamento da imagem e ela não parece natural, e é por isso que Levei ao StackOverflow para obter ajuda sobre como fazer isso de forma nativa.
Pan Ziyue

Respostas:


198
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60, -60)
                                                         forBarMetrics:UIBarMetricsDefault];

Em seguida, você pode remover o título do item do botão Voltar.

Se você usa o Storyboard, pode definir o botão Voltar do inspetor de atributos de navegação com espaço.


95
Há um problema com grandes títulos: eles não estão centradas mas deslocado para a direita, como se o texto do botão de volta ainda estava lá
sonxurxo

11
Isso não funciona se o usuário tiver ativado "Acessibilidade - formas botão"
Mikael Bartlett

22
Eu acho que esta é uma resposta melhor:[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];
benjamin

19
Qualquer solução com números mágicos é uma má idéia. Com o empurrão para a execução automática, classes de tamanho, recursos de acessibilidade, etc., usando valores constantes como esse certamente o incomodará.
Michael Peterson

3
Para melhorar o comentário de benjamin, você deve definir isso UIControlStateHighlightedtambém
n_b

411

Para definir o título do botão Voltar para um controlador de exibição sem alterar seu título, use:

Objetivo-C:

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

Rápido:

navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

Para deixar claro, isso é feito no controlador de exibição que você veria se apertasse o botão Voltar. ou seja, em vez de ver '<Configurações', você deseja apenas ver '<'; em seguida, no seu SettingsViewController, você deve colocar isso no seu init. Então você não terá nenhum problema do título quando estiver olhando para o próprio controlador de exibição.


1
Não sei por que a outra resposta está marcada como correta, é apenas remover o título para que o botão voltar doent tenha um "título" para mostrar, mas essa não é a abordagem correta! Essa deve ser a resposta certa.
Pach 15/05

8
Também para quem usa o Swift, é navigationItem.backBarButtonItem = UIBarButtonItem (title: "", style: .Plain, target: nil, action: nil). Não é difícil converter de Obj-C para Swift, mas vou poupar o troublef
Zoyt

15
@BenjaminPiette, você está chamando isso no UIViewController que veria se apertasse o botão voltar? Não é o UIViewController que exibe o botão Voltar.
DonnaLea

2
Que solução elegante! Obrigado. Apenas não parecia certo fazer a coisa da compensação.
hyd00

2
essa solução funcionará perfeitamente se você escrever esta linha de código no controlador anterior na pilha de navegação.
Bohdan Savych

128

Se você estiver usando Storyboards, poderá acessar Attributes Inspectoro ViewController Navigation Item(clique em Navigation Bar) e definir a Back Buttonpropriedade como "" (um caractere de espaço). Isso definirá o título do botão Voltar para um caractere de espaço, deixando a divisa visível. Não há necessidade de mexer com o código.

example image

Observe que isso definirá o Back Buttontítulo do botão Voltar que segue para este View Controller daquele que foi pressionado em cima dele, e não do Back Buttonque será exibido dentro deste controlador!


10
Eu gostaria de poder votar mais: "Observe que isso definirá o título do botão Voltar para o botão Voltar que segue para este View Controller do formulário que foi pressionado em cima dele, não para o botão Voltar que será exibido dentro deste Controlador!"
Jayson Lane

121

Isso funciona para eu exibir apenas a divisa 'de volta' sem nenhum texto:

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

Defina essa propriedade no viewDidLoadView Controller apresentando a barra de navegação e ele fará o truque.

Nota: Eu o testei apenas no iOS 7, que está dentro do escopo da pergunta.


33
Isso tem o efeito colateral de remover o rótulo do título no meio da barra de navegação.
Pwner

7
Defina o título do VC que está pressionando em 'viewWillAppear' com a mesma propriedade. Desta forma, não é removido.
Guto Araujo

5
Mudei esse trecho de código para -viewDidLoado VC que não quero o texto Voltar. No entanto, o que descobri mais tarde foi que, quando apago o 2º VC do navigationControllertexto do título, aparece logo depois, não imediatamente. Eu acho que um vídeo teria ilustrar isso melhor, então aqui está: ligação
Pan Ziyue

1
Esta não é a melhor resposta, consulte a resposta de andyleehao: [[aparência do UIBarButtonItem] setBackButtonTitlePositionAdjustment: UIOffsetMake (0, -60) forBarMetrics: UIBarMetricsDefault];
Lmnbeyond

1
Esta é a resposta correta, de acordo com a documentação da Apple: "Quando o receptor está na pilha de itens de navegação e é o segundo a partir do topo - em outras palavras, seu controlador de visualização gerencia as visualizações pelas quais o usuário navegaria - o valor nessa propriedade é usado para o botão voltar na barra de navegação superior. Se o valor dessa propriedade for nulo, o sistema utilizará a string "Voltar" como o texto do botão voltar. "
Raphael Oliveira

27

Ao definir o título do botão, use @ "" em vez de @ "".

--EDITAR--

Alguma coisa muda quando você tenta outras strings? Estou usando o seguinte código com êxito:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:backString style:UIBarButtonItemStyleDone target:nil action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];

backString é uma variável definida como @ "" ou @ "Back", dependendo se eu estiver no iOS 7 ou em uma versão inferior.

Uma coisa a observar é que esse código não está no controlador da página para a qual desejo personalizar o botão Voltar. Na verdade, ele está no controlador antes dele na pilha de navegação.


Hmm, o iOS 7 parece não mudar isso. Ele continua usando "Voltar" como o título. Se eu colocar em setLeftBarButtonItem:backButtonvez disso, nada estaria lá.
Pan Ziyue

1
Se for esse o caso, e nada acontecer quando você definir o título para outra coisa, acho que você terá que tentar mover seu código para o controlador de exibição pai. Estou usando o código que postei acima no meu método prepareForSegue.
Kamaros 30/09

27

insira a descrição da imagem aqui

Às vezes, é útil ver as coisas em contexto. Aqui está um projeto mínimo que oculta o texto "voltar", mas ainda mostra a seta.

Storyboard

insira a descrição da imagem aqui

Há um show segue do botão "Show Second View Controller" para o segundo controlador de exibição.

Também adicionei um item de navegação ao segundo controlador de exibição para que ele tivesse um título. Isso é opcional. Não afeta o botão Voltar.

Código

FirstViewController.swift

import UIKit
class FirstViewController: UIViewController {

    @IBAction func showSecondViewControllerButtonTapped(sender: UIButton) {

        // hide the back button text
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
}

SecondViewController.swift

import UIKit
class SecondViewController: UIViewController {
    // Nothing at all needed here
}

Método alternativo (apenas IB, sem código)

No storyboard, selecione o item de navegação para o primeiro controlador de exibição (não o segundo). Basta inserir um espaço para o texto do botão Voltar.

insira a descrição da imagem aqui


Conceito-chave que "para o primeiro controlador de exibição (não o segundo)" como é o nome do VC que você deseja retornar, portanto é responsabilidade atribuir esse título.
buguibu

15
self.navigationController.navigationBar.topItem.title = @"";

1
Você pode usar backItem em vez de topItem. TopItem oculta o título, enquanto backItem oculta o título do botão Voltar.
Ravi Ojha

2
Esta é a única solução se o childViewController é em profundidade 2+ em crianças do NavigationController empilhar
Nathaniel Blumer

2
Isso também removerá o título do controlador de exibição anterior. Na maioria dos casos, isso vai chupar
calzone

11

No iOS7, a Apple introduziu duas novas propriedades no UINavigationBar, 'backIndicatorTransitionMaskImage' e 'backIndicatorImage'.

Simplesmente ligando uma vez:

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"your_image"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"your_image_mask"]];

Ele renderizará uma imagem personalizada em vez do glifo padrão da viga, herdando a cor da tonalidade da keyWindow.

E para remover o título, sugiro a resposta de Kamaros. Lembre-se de chamar esse código no controlador de exibição que está pressionando seu novo controlador de exibição. Removendo o texto do título de um iOS UIBarButtonItem


Para ajustar a cor da tonalidade [[aparência da UINavigationBar] setTintColor: [UIColor whiteColor]];
Mazen Kasser 31/10/2013

10

Não tive muito sucesso com as respostas fornecidas, mas encontrei uma solução realmente simples. No storyboard, você pode clicar no item de navegação do UIViewController e definir o texto do botão Voltar. Coloquei-o em um único espaço '' e isso me deu o comportamento que estava procurando.insira a descrição da imagem aqui


10

Isso funcionou para mim no iOS10. Chame isso de viewDidLoad do controlador de exibição.

self.navigationController?.navigationBar.topItem?.title = ""

6

A solução simples para esse problema, trabalhando no iOS7 e no 6, é definir a exibição de título personalizada em viewDidLoad:

- (void)viewDidLoad {

    [super viewDidLoad];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    titleLabel.text = self.title;
    titleLabel.backgroundColor = [UIColor clearColor];

    [titleLabel sizeToFit];

    self.navigationItem.titleView = titleLabel;
}

Em viewWillAppear: você pode chamar com segurança

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

Como a visualização do título é personalizada, ela não será substituída ao retornar à pilha de navegação.


Eu só precisava da última parte do código e não do UILabel em branco. Eu estava chamando o [self.navigationItem.backBarButtonItem setTitle:@" "];viewWillAppear, mas ele não estava funcionando nas visualizações apresentadas depois de descartar uma visualização modal.
Diziet

6

Na verdade, você pode fazer isso com apenas um truque:

Substitua a UINavigationBarclasse e adicione esta linha de código:

- (void)layoutSubviews{
    self.backItem.title = @"";
    [super layoutSubviews];
}

Então inicialize seu UINavigationController com esta classe UINavigationBar personalizada ... etc.UINavigationController * navController = [[UINavigationController alloc] initWithNavigationBarClass:[CBCNavigationBar class] toolbarClass:nil];

Espero que isto ajude


Isso funcionou para mim. Embora pareça que exista uma ligeira gagueira na animação push no iOS 7: o título parece abrir espaço para o botão Voltar e, em seguida, centraliza-se, pois não há nenhum.
Zekel 7/08

Sim, tente usar o titleView personalizado em vez de definir o item de navegação diretamente. Eu acho que isso deve resolver o seu problema.
Rordulu

essa solução é incrível porque é global para todas as barras de navegação que possuem a subclasse. Obrigado
Yetispapa 7/17

5

Consegui juntar algo usando a resposta de DonnaLea. É assim que a solução aparece na minha subclasse UIViewController:

var backItemTitle:String?

override func viewDidLoad() {
    super.viewDidLoad()

    //store the original title
    backItemTitle = self.navigationController?.navigationBar.topItem?.title

    //remove the title for the back button
    navigationController?.navigationBar.topItem?.title = ""
}

override func willMoveToParentViewController(parent: UIViewController?) {
    super.willMoveToParentViewController(parent)
    if parent == nil {

        //restore the orignal title
        navigationController?.navigationBar.backItem?.title = backItemTitle
    }
}

O problema com a resposta original é que ele remove o título do controlador quando você volta a ele. A tentativa de redefinir o título em viewWillDisappear é muito tarde no processo de transição; Isso faz com que o título volte novamente ao invés de animar bem. No entanto, o willMoveToParentViewController acontece mais cedo e permite o comportamento correto.

Advertência: Eu só testei isso com um push / pop normal do UINavigationController. Pode haver um comportamento inesperado adicional em outras situações.


4

No método prepareForSegue: do seu primeiro ViewController, você define esse título para @ ""; portanto, quando a próxima exibição for pressionada, ele exibirá o título anterior do ViewController, que será @ "".

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    self.navigationItem.title = @" ";
}

O único problema com isso é que, quando você pressiona o botão Voltar, sua visualização anterior não possui título, portanto, você pode adicioná-lo novamente em viewWillAppear:

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

Não gosto muito desta solução, mas funciona e não encontrei outra maneira de fazê-lo.



3

Nenhuma das respostas me ajudou. Mas um truque funcionou - eu acabei de limpar o título do controlador de exibição que pressionou (para onde o botão voltar) está antes de pressioná-lo.

Portanto, quando a visualização anterior não tiver um título, no iOS 7, o botão Voltar terá apenas uma seta, sem texto.

Na viewWillAppearvisão de empurrar, coloquei de volta o título original.


1
Hmm, esse truque funciona. No entanto, parece que as palavras lá em cima piscam algumas vezes. Solução não muito boa, mas boa. +1
Pan Ziyue 17/10/2013

3
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];

    [[UIBarButtonItem appearance] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];

Eu estava tendo o mesmo problema e fiz dessa maneira.

--EDITAR--

Essa é uma solução quando você realmente deseja remover o texto do título de todo o UIBarbuttonItem. Se você deseja remover apenas o título do item do botão da barra traseira, não existe uma solução simples e conveniente. No meu caso, como eu tenho apenas alguns UIBarButtonItems que precisam mostrar o texto do título, apenas alterei o titleTextAttributes desses botões específicos. Se você quiser ser mais específico, use o código abaixo, que mudará apenas os botões da barra de navegação:

NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];

1
Isso funciona para mim, no entanto, você pode ver brevemente o texto ao retornar.
Diziet

3
@Diziet tentar adicionar o mesmo para o Estado UIControlStateHighlightedbem
CoderPug

2
Isso funciona bem, mas isso também "oculta" todos os outros botões, não apenas o botão Voltar ... Alguma idéia para resolver isso?
Urkman

3

Isso está usando subclasse navigationController remove o "Voltar".

Estou usando isso para removê-lo, permanentemente através do aplicativo.

//.h
@interface OPCustomNavigationController : UINavigationController 

@end

//.m
@implementation OPCustomNavigationController

- (void)awakeFromNib
{
    [self backButtonUIOverride:YES];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self backButtonUIOverride:NO];

    [super pushViewController:viewController animated:animated];
}

- (void)backButtonUIOverride:(BOOL)isRoot
{
    if (!self.viewControllers.count)
        return;

    UIViewController *viewController;

    if (isRoot)
    {
        viewController = self.viewControllers.firstObject;
    }
    else
    {
        int previousIndex = self.viewControllers.count - 1;

        viewController = [self.viewControllers objectAtIndex:previousIndex];
    }

    viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@""
                                                                                       style:UIBarButtonItemStylePlain
                                                                                      target:nil
                                                                                      action:nil];
}

@end

3
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefaultPrompt];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(10.0, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],
                                                               NSFontAttributeName:[UIFont systemFontOfSize:1]}
                                                    forState:UIControlStateNormal];

1
Por favor, adicione uma explicação à sua resposta.
28415 Alex

1 fazer a mesma cor que a barra de navegação 2 faça a pequena o suficiente tamanho do texto não apertar o título
Bill Xie

Analisei sua resposta, você deve sempre apoiá-la.
28415 Alex

2

Ocultar o botão Voltar Título da barra de navegação

UIBarButtonItem *barButton = [[UIBarButtonItem alloc] init];
barButton.title = @""; // blank or any other title
self.navigationController.navigationBar.topItem.backBarButtonItem = barButton;

2

Aqui está o que estou fazendo, que é mais simples de remover o título do botão Voltar

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar?.backItem?.title = ""
}

2

Swift 3.1 Você pode fazer isso implementando o método delegado de UINavigationController. Ele ocultará o título apenas com o botão Voltar; ainda obteremos a imagem da seta de retorno e a funcionalidade padrão.

func navigationController(_ navigationController: UINavigationController, 
  willShow viewController: UIViewController, animated: Bool) {
        let item = UIBarButtonItem(title: " ", style: .plain, target: nil, 
                    action: nil)
        viewController.navigationItem.backBarButtonItem = item
    }

1

Você também pode usar isso:

UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init];
temporaryBarButtonItem.title = @"";
self.navigationItem.backBarButtonItem = temporaryBarButtonItem;

[temporaryBarButtonItem release];

Isso funciona para mim


1
case : <Back as <

override func viewWillAppear(animated: Bool) {
navigationController!.navigationBar.topItem!.title = ""
    }

1

Solução perfeita globalmente

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Normal)
    UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Highlighted)

    return true
}

solução dumpest de tudo ... sua também usar o espaço como antes ... é apenas tornar-se transparente ...
Laszlo

Ele remove o texto de todos os UIBarButtonItems do aplicativo
Mikel Sanchez

1

Crio uma classe personalizada para UINavigationControllere aplico-a a todos os controladores de navegação no meu aplicativo. Dentro dessa UINavigationControllerclasse personalizada , defino o UINavigationBardelegado para selfquando a exibição for carregada.

- (void)viewDidLoad {
    self.navigationBar.delegate = self;
}

Então eu implemento o método delegado:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item {

    // This will clear the title of the previous view controller
    // so the back button is always just a back chevron without a title
    if (self.viewControllers.count > 1) {
        UIViewController *previousViewController = [self.viewControllers objectAtIndex:(self.viewControllers.count - 2)];
        previousViewController.title = @"";
    }
    return YES;
}

Dessa forma, eu simplesmente atribuo minha classe personalizada a todos os meus controladores de navegação e limpa o título de todos os botões Voltar. E, por questões de clareza, eu sempre defino o título para todos os meus outros controladores de exibição, viewWillAppearpara que o título seja sempre atualizado imediatamente antes da exibição da exibição (caso seja removida por truques como este).


1

Basta digitar um único espaço para o item de navegação do botão Voltar!


1
Isso é mais adequado como comentário do que como resposta.
Al Lelopath

1

Se, como eu, você estiver usando uma exibição personalizada em vez de UINavigationBare estiver com o botão Voltar, precisará fazer um trabalho que pareça um pouco desleixado.

[self.navigationController.navigationBar setHidden:NO];
self.navigationController.navigationBar.topItem.title = @"";
[self.navigationController.navigationBar setHidden:YES];

Parece que, se não for apresentado, não importa o que tente mostrar um título, isso significa que ele é mostrado e oculto antes de ser desenhado e resolver o problema.


1
extension UIViewController{
    func hideBackButton(){
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
}

1

Eu criei uma categoria de configuração zero muito simples para ocultar todos os títulos dos botões voltar através do aplicativo. Você pode conferir aqui . Esta pergunta já aceitou resposta, mas para outras pode ser útil.

EDITAR:

arquivo .h

#import <UIKit/UIKit.h>

@interface UINavigationController (HideBackTitle)
extern void PJSwizzleMethod(Class cls, SEL originalSelector, SEL swizzledSelector);

@end

arquivo .m

#import "UINavigationController+HideBackTitle.h"
#import <objc/runtime.h>


@implementation UINavigationController (HideBackTitle)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        PJSwizzleMethod([self class],
                    @selector(pushViewController:animated:),
                    @selector(pj_pushViewController:animated:));
    });
}

- (void)pj_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    UIViewController *disappearingViewController =  self.viewControllers.lastObject;
    if (disappearingViewController) {
        disappearingViewController.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    }
    if (!disappearingViewController) {
        return [self pj_pushViewController:viewController animated:animated];
    }
    return [self pj_pushViewController:viewController animated:animated];
}



@end

void PJSwizzleMethod(Class cls, SEL originalSelector, SEL swizzledSelector)
{
    Method originalMethod = class_getInstanceMethod(cls, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);

    BOOL didAddMethod =
    class_addMethod(cls,
                originalSelector,
                method_getImplementation(swizzledMethod),
                method_getTypeEncoding(swizzledMethod));

    if (didAddMethod) {
        class_replaceMethod(cls,
                        swizzledSelector,
                        method_getImplementation(originalMethod),
                        method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.