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.