Remova o texto do botão Voltar mantendo o ícone

92

Quero remover o texto do botão Voltar, mas quero manter o ícone. eu tentei

let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: navigationController, action: nil)
navigationItem.leftBarButtonItem = backButton

No entanto, isso remove completamente o texto e o ícone.

lmiguelvargasf
fonte

Respostas:

98

O método de @ rmd2 é quase correto, mas em vez disso, você deve selecionar a barra de navegação do controlador para a qual o botão Voltar apontará e digite " "no campo Botão Voltar.

insira a descrição da imagem aqui

m8labs
fonte
1
pior forma, se o viewcontroller não tiver a barra de navegação terei que adicionar para remover o texto
Daniel Beltrami
142

Eu sei que isso já tem uma resposta, mas você também pode fazê-lo em código (caso esteja trabalhando com pontas)

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

Adicione o acima no primeiro controlador de visualização.

Observe que você precisa fazer isso para cada controlador de visualização que está empurrando. Portanto, se você tiver 3 controladores de visualização e quiser remover o texto de volta de todos eles, será necessário adicionar a linha nos controladores de visualização 1 e 2.

d9rad
fonte
5
Esta é a melhor solução que vi até agora sem problemas
lostAtSeaJoshua
4
.Plainfoi alterado para .plain. Sem p maiúsculo.
Gal
Perfeito..! Isso é o que eu quero.
JD.
Melhor solução. Obrigado.
Baran Emre
1
@ GastónAntonioMontes, ela não funciona em iOS13, mas é um contador pouco intuitivo: o título vazio backBarButtonItem deve ser declarada no empurrando controlador de vista, não o empurrou um
Martin
49

Depois de pesquisar muito, encontrei a solução melhor e simples, que afetará todos os viewControllers escritos em Swift 4.2 e também trabalhando em Swift 5

extension UIViewController {
    open override func awakeFromNib() {
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }  
}
iOS Lifee
fonte
Bem-vindo @ e.dimitrow
iOS Lifee
1
Funciona como charme
Jerry Okafor
3
Observe que isso só funcionará se seu ViewController estiver contido em um Storyboard ou Nib ...
Nathaniel Blumer
1
Uma solução genial!
WM de
3
Isso costumava funcionar para mim, mas não funciona mais (ainda funciona nos simuladores do iOS 12, mas não no iOS 13 mais recente) ...
tanya
35

O texto do botão Voltar depende do título da visualização principal.

O truque é limpar o título se a visualização principal desaparecer e configurá-lo novamente se for mostrado novamente:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // needed to clear the text in the back navigation:
    self.navigationItem.title = " "
}

override func viewWillAppear(_ animated: Bool) {
   
    super.viewWillAppear(animated)
    self.navigationItem.title = "My Title"
}
Stefan
fonte
33

Se você quisesse remover o título de um botão de voltar de um controlador de vista empurrado, digamos que <Settingspara <em subSettingsViewController então você tem que definir backBarButtonItem título de SettingsViewController () viewWillDisappear método.

Objective-C:

- (void)viewWillDisappear:(BOOL)animated
    [super viewWillDisappear:animated];
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil];
}

Rápido:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Muhammad Umair
fonte
1
.Plainfoi alterado para .plain. Sem p maiúsculo.
Gal
1
A resposta precisa ser atualizada para o comportamento de searchController. Por exemplo, se você usar um resultsVC separado e tocar em um item que empurra outro VC, o método viewWillDisappear do searchController inicial não é chamado, portanto, o título ainda está lá
H4Hugo
Essa não é uma boa abordagem se você está procurando uma solução para telas em todo o aplicativo. - Se você adicionar este código a algum "Base View Controller", viewWillDisappear do primeiro view controller será chamado após viewDidAppear do segundo view controller (onde você normalmente define o título) ... isso irá bagunçar os títulos. A melhor maneira é sobrescrever o botão Voltar
Mithra Singam
Obrigado pela solução perfeita
SURESH SANKE
28

Se você quiser a seta para trás, coloque o código a seguir no arquivo AppDelegate no método didFinishLaunchingWithOptions.

Para Swift

let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)
Pradeep Bishnoi
fonte
2
eu gosto deste porque você pode padronizar o estilo do seu aplicativo em um único arquivo e chamá-lo uma vez do delegado do aplicativo
Aaronium112
4
É uma solução muito boa e rápida, mas ... pode ser complicado se você tiver outros itens de botão da barra, exceto o de trás
:)
3
Uma observação, se você implementar apenas o atributo ".normal", verá o texto ao clicar. Adicione a mesma linha para ".selected", ".highlighted" e ".disabled." para garantir que você não veja o texto piscando.
Nick N
1
Acho que isso terá um efeito colateral, outros botões da barra além dos botões de voltar também serão afetados e terão uma cor de texto clara :(
dhin
23

No meu caso, para ícone e título personalizados, funcionou (Swift 4)

    let imgBack = UIImage(named: "ic_back")

    navigationController?.navigationBar.backIndicatorImage = imgBack
    navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBack

    navigationItem.leftItemsSupplementBackButton = true
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
Rafiqul Hasan
fonte
1
a última linha desse código funcionou perfeitamente para mim. Todas as outras sugestões não funcionaram, provavelmente porque meus controladores de visualização são todos controlados por um controlador de navegação. Nesse caso, o navigationController? é realmente necessário.
Salx
Você precisará das quatro primeiras linhas se quiser adicionar um botão Voltar personalizado. Caso contrário, a última linha resolverá o problema.
Rafiqul Hasan
14

Resolvi esse problema adicionando um "" no título do StoryBoard do ViewController anterior. Apenas um espaço, não vazio; D

insira a descrição da imagem aqui

rmd2
fonte
Preciso que a tela anterior tenha um título, então acho que isso não vai funcionar para mim.
lmiguelvargasf
2
Eu anulei esse título, mas ainda o título está vindo no botão traseiro
Himali Shah
1
não deixe em branco o campo Título, coloque "" (espaço) no campo do Botão Voltar
Kiril S.
13

Finalmente encontrei a solução perfeita.

Basta adicionar uma imagem transparente e adicionar o código a seguir em seu AppDelegate.

UIBarButtonItem.appearance().setBackButtonBackgroundImage(#imageLiteral(resourceName: "transparent"), for: .normal, barMetrics: .default)
Lalit Kumar
fonte
1
Esta é definitivamente a melhor resposta. Anteriormente, eu estava usando o UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustmenthack que a maioria das outras respostas recomendam, mas foi quebrado no iPhone X para controladores de visualização com títulos longos. Esta solução funciona perfeitamente.
Ned
3
Melhor resposta. Funcionou melhor do que a cor de texto transparente.
William T.
1
Melhor solução o que usei nos últimos 4 anos! Você faz isso uma vez, em um lugar e para todos os controladores de visualização !!!
korgx9
1
Quando tentei fazer isso com o iOS 12, o texto ainda aparecia ao lado da imagem. :(
Sean McMains
13

em rápido 4

self.navigationController?.navigationBar.topItem?.title = ""
Amalendu Kar
fonte
Obrigado, isso me ajudou, (Swift 4.0, Xcode 10.1, iOS 12.1.1), obrigado
infinity_coding7
3
MAS, você perderá seu título no pai vc
Wei Lu
1
Se um título grande estiver presente, topItem será largeTitle. Não funciona
Saranjith
10

Para Swift 4+ colocar estas linhas no AppDelegatenodidFinishLaunchingWithOptions

let BarButtonItemAppearance = UIBarButtonItem.appearance()

BarButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)      
BarButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)
BilalReffas
fonte
Quando você define a aparência no delegado do aplicativo, a cor de primeiro plano clara é para cada UIBarButtonItem, não é? Portanto, se eu adicionar um UIBarButtonItem com um texto, terei que alterar a cor do primeiro plano para este botão manualmente?
kuzdu
1
Isso é bom, mas quando você pressiona o botão Voltar, ainda mostra o texto
William T.
Funciona, mas faz com que outro botão da barra desapareça no iOS 11. A resposta de Rafiqul Hasan acima pode resolver o problema
huync
8

Isso está funcionando para mim

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
RomanV
fonte
O correto. No ios 13, navigationItem.backBarButtonItem não funciona. Isso salvou minhas horas de esforços. Obrigado
Manish
5

Se você tem um ViewControllerA e deseja navegar para o ViewControllerB, no ViewControllerA, você deve definir o navigationItem atual com um novo UIBarButtonItem e o título para uma string com espaço em branco antes de enviar para outro controlador de visualização:

Defina o título como uma string com um espaço em branco, você não pode definir nil ou "" (string vazia) porque o valor padrão é nil

let backItem = UIBarButtonItem()
backItem.title = " "
navigationItem.backBarButtonItem = backItem
let controllerB = ViewControllerB()
navigationController?.pushViewController(controllerB, animated: true)
Bradley
fonte
5

Coloque este código em cada VC que empurra outro

navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
Polina Hill
fonte
3
let button: UIButton = UIButton (type: UIButtonType.Custom)
button.setImage(UIImage(named: "imageName"), forState: UIControlState.Normal)
button.addTarget(self, action: "backButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem(customView: button)

self.navigationItem.leftBarButtonItem = barButton

func backButtonPressed(btn : UIButton) {

    // Your code
}
Hasya
fonte
3

Para remover todos os controladores de visualização em uma pilha de controladores de navegação:

subclasse UINavigationController e adicione este:

override func show(_ vc: UIViewController, sender: Any?) {
    setEmptyBackButton(vc)
    super.show(vc, sender: sender)
}

override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    setEmptyBackButton(viewController)
    super.pushViewController(viewController, animated: animated)
}

func setEmptyBackButton(_ viewController: UIViewController) {
    viewController.navigationItem.backBarButtonItem =
        UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Gaston Gonzalez
fonte
2

Às vezes não funciona alterar apenas a cor do título, no caso de o título ser longo. Porque isso pode deslocar o título da barra de navegação para a esquerda. Portanto, para evitar isso, você pode precisar mudar o título do botão da barra horizontalmente, além de torná-lo transparente:

let barButtonItemAppearance = UIBarButtonItem.appearance()
    barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
    barButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)
Max Niagolov
fonte
1

Para mim, isso funcionou:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)
    self.navigationItem.title = " "
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationItem.title = "my amazing title"
    navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}

Observe que se você definir apenas o título sem modificar o backBarButtonItem, ele parecerá funcionar. Mas se você tentar voltar usando um gesto e cancelar e permanecer no controlador de visualização empurrado, o título de volta voltará.

Trabalhando em Swift 4

mrc
fonte
Você poderia explicar?
mrc
Tenho um controlador que sempre mostra o texto Voltar com o botão Voltar. O código acima não funciona no meu caso
Shahbaz Akram
1

Você deve selecionar a barra de navegação do controlador DE onde o botão Voltar apontará e digite "" no campo Botão Voltar.

por exemplo, se você estiver empurrando o controlador A para o controlador B, coloque um espaço em branco na barra de navegação do controlador A.

Tushar Raikwar
fonte
1

Xcode 10, Swift 4+

Resposta semelhante às outras aqui, mas é importante notar que se o texto ainda não for apagado, você deve clicar em Espaço e depois em Enter.

insira a descrição da imagem aqui

Aishat Olowoshile
fonte
1

Detalhes

  • Xcode versão 10.2.1 (10E1001), Swift 5

Solução

1. Crie uma classe personalizada do UINavigationController

import UIKit

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

extension NavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController.navigationItemBackButtonTextIsHidden {
            viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        }
    }
}

2. Adicionar extensão UIViewController

import UIKit

extension UIViewController {
    @objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}

3. Atualize sua classe ViewController

import UIKit

class ViewController: UIViewController {
    override var navigationItemBackButtonTextIsHidden: Bool { return true }
}

Amostra completa

import UIKit

// MARK: - ViewController

class ViewController: UIViewController {

    var screenCounter = 1

    override func viewDidLoad() {
        super.viewDidLoad()
        setupNavigationItem()
    }

    override var navigationItemBackButtonTextIsHidden: Bool { return (screenCounter % 2) == 0 }
}

extension ViewController {

    private func setupNavigationItem() {
        navigationItem.title = "VC \(screenCounter)"
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "push", style: .plain, target: self, action: #selector(pushBarButtonTouchedUpInside))
    }

    @objc func pushBarButtonTouchedUpInside(button: UIBarButtonItem) {
        guard let navigationController = navigationController else { return }
        let viewController = ViewController()
        viewController.screenCounter = screenCounter + 1
        viewController.view.backgroundColor = .white
        navigationController.pushViewController(viewController, animated: true)
    }
}

// MARK: - NavigationController

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

extension NavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController.navigationItemBackButtonTextIsHidden {
            viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        }
    }
}

// MARK: - UIViewController extension

extension UIViewController {
    @objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}

Resultado

insira a descrição da imagem aqui

Vasily Bodnarchuk
fonte
1

Uma alternativa para substituir tudo ViewControllerspara mim era estender UINavigationControllere definir o backBarButtonItemdo topViewController.

Swift 5 no Xcode 11.2.1:

extension UINavigationController {
    override open func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let backButton = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
        self.topViewController?.navigationItem.backBarButtonItem = backButton
    }
}
Azarado
fonte
1

A maneira mais fácil de fazer isso programaticamente é definir a backBarButtonItempartir do controlador de visualização pai (um controlador que chama push).

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

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

Mais detalhes aqui https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/

Sarunw
fonte
1

Você pode remover o texto do botão Voltar usando um método de delegação de UINavigationController.

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

}

extension CustomNavigationController: UINavigationControllerDelegate {
    
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: String(), style: .plain, target: nil, action: nil)
    }
    
}
keval
fonte
0

No Xcode 9.2 com Swift, funcionava assim:

override func viewWillDisappear(_ animated: Bool) {
   super.viewWillDisappear(true)
   navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Thiago Bueno
fonte
0

Para o caso em que não temos controle do controlador de visualização anterior (ou seja, se estivermos trabalhando em uma estrutura), podemos excluir o título do botão Voltar como segue:

// For iOS 10
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = String()

// For iOS 11
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = nil

O que ele faz é navegar até o último item da pilha de navegação e deletar seu título anterior. Certifique-se de salvar o original quando nosso controlador de visualização aparecerá:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    originalBackButtonTitle = navigationController?.navigationBar.items?.last?.backBarButtonItem?.title
    // Delete title somewhere here...
}

e, em seguida, reatribua-o, para não interromper qualquer parte do aplicativo:

override func viewWillDisappear(_ animated: Bool) {
    navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = originalBackButtonTitle
    super.viewWillDisappear(animated)
}
Ángel Téllez
fonte
0

Isso resolverá seu problema:

    import UIKit

    extension UINavigationController{

    func customizeBackArrow(){
        let yourBackImage = UIImage(named: "icon_back_arrow")
        self.navigationBar.backIndicatorImage = yourBackImage
        self.navigationBar.tintColor = Common.offBlackColor
        self.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
        navigationItem.leftItemsSupplementBackButton = true
        self.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", 
           style: .plain, target: self, action: nil)

    }
}
Mossman252
fonte
0

Tentei algumas respostas e não consigo fazê-las funcionar em todos os casos. Portanto, esta é uma solução alternativa para não afetar o título da barra de navegação se ela estiver definida.

    guard let items = viewController.navigationController?.navigationBar.items else { return }
    for item in items {
        if item.title == nil {
            item.title = ""
        }
    }
Rikard Platus
fonte
0

A maneira programática fácil, sem efeitos colaterais indesejados, é inicializar o navigationItem.backBarButtonItem com um item vazio no método awakeFromNib do controlador de origem (aquele de onde você está navegando):

override func awakeFromNib() {
    super.awakeFromNib()
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

Nota: Se você inicializou o botão Voltar mais tarde, como no método viewDidLoad () , você perderia a funcionalidade de deslizar para trás (deslizar da esquerda para a direita leva você um passo para trás na pilha de navegação).

Então, se você quiser textos de botão de voltar diferentes para controladores de destino diferentes e se estiver usando segues, você pode definir o título no método prepare (para segue :, sender :) , como este:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let item = navigationItem.backBarButtonItem {
        switch segue.identifier {
        case "SceneOne": item.title = "Back"; break
        case "SceneTwo": item.title = "Home"; break
        case "SceneThree": item.title = nil; break // Use this scene's title
        default: item.title = "" // No text
        }
    }
}
Jiri Volejnik
fonte