Rimuovi il testo dal pulsante Indietro mantenendo l'icona


92

Voglio rimuovere il testo dal pulsante Indietro, ma voglio mantenere l'icona. Ho provato

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

Tuttavia, questo rimuove completamente il testo e l'icona.

Risposte:


98

Il metodo di @ rmd2 è quasi corretto, ma invece dovresti selezionare la barra di navigazione del controller a cui punterà " "il pulsante Indietro e digitare nel campo Pulsante Indietro.

inserisci qui la descrizione dell'immagine


1
peggior modo, se il viewcontroller non ha la barra di navigazione dovrò aggiungere per rimuovere il testo
Daniel Beltrami

142

So che questo ha già una risposta, ma puoi anche farlo in codice (nel caso tu stia lavorando con i pennini)

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

Aggiungi quanto sopra nel primo controller di visualizzazione.

Nota che devi farlo per ogni controller di visualizzazione che sta spingendo. Quindi, se hai 3 controller di visualizzazione e desideri rimuovere il testo in fondo da tutti loro, dovrai aggiungere la riga nei controller di visualizzazione 1 e 2.


5
Questa è la migliore soluzione che ho visto finora non mi dà problemi
lostAtSeaJoshua

4
.Plainè stato cambiato in .plain. Nessun capitale p.
Gal

Perfetto..! È quello che voglio.
JD.

Soluzione migliore. Grazie.
Baran Emre

1
@ GastónAntonioMontes, funziona su iOS13, ma è un po 'contatore intuitivo: il titolo vuoto backBarButtonItem dovrebbe essere dichiarato sulla spinta controller della vista, non l' ha spinto uno
Martin

49

Dopo aver cercato molto ho trovato la soluzione migliore e semplice, questo interesserà tutti i viewController scritti in Swift 4.2 e funzionanti anche in Swift 5

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

Benvenuto @ e.dimitrow
iOS Lifee

1
Funziona a meraviglia
Jerry Oka per il

3
Nota che questo funzionerà solo se il tuo ViewController è contenuto in uno Storyboard o Nib ...
Nathaniel Blumer

1
Una soluzione geniale!
WM

3
Questo funzionava per me, ma non più (funziona ancora sui simulatori iOS 12, ma non sull'ultimo iOS 13) ...
tanya

35

Il testo del pulsante Indietro dipende dal titolo della vista principale.

Il trucco è cancellare il titolo se la vista principale scompare e impostarlo di nuovo se viene mostrato di nuovo:

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"
}

33

Se si desidera rimuovere il titolo di un pulsante Indietro da un controller di visualizzazione premuto, <Settingsad esempio <in subSettingsViewController, è necessario impostare il titolo backBarButtonItem nel metodo viewWillDisappear () di SettingsViewController .

Obiettivo-C:

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

Swift:

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

1
.Plainè stato cambiato in .plain. Nessun capitale p.
Gal

1
La risposta deve essere aggiornata per il comportamento di searchController. Ad esempio, se utilizzi un risultatoVC separato e tocchi un elemento che spinge un altro VC, il metodo viewWillDisappear dal searchController iniziale non viene chiamato, quindi il titolo è ancora lì
H4Hugo

Questo non è un buon approccio se stai cercando una soluzione per gli schermi nell'intera app. - Se aggiungi questo codice a qualche "Base View Controller", viewWillDisappear del primo controller di visualizzazione verrà chiamato dopo viewDidAppear del secondo controller di visualizzazione (dove di solito imposti il ​​titolo) ... questo rovinerà i titoli. Il modo migliore è sovrascrivere il pulsante Indietro
Mithra Singam

Grazie soluzione perfetta
SURESH SANKE

28

Se vuoi la freccia indietro, inserisci il codice seguente nel file AppDelegate nel metodo didFinishLaunchingWithOptions.

Per Swift

let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)

2
mi piace perché puoi standardizzare lo stile della tua app in un unico file e chiamarlo una volta dal delegato dell'app
Aaronium112

4
È una soluzione davvero bella e veloce, ma ... potrebbe essere complicato se hai altri elementi del pulsante della barra tranne quello posteriore
:)

3
Un'osservazione, se implementi solo l'attributo ".normal", vedrai il testo al clic. Aggiungi la stessa riga per ".selected", ".highlighted" e ".disabled". per assicurarti di non vedere il testo sfarfallio.
Nick N

1
Penso che questo avrà un effetto collaterale, anche altri pulsanti della barra oltre ai pulsanti posteriori saranno interessati e avranno un colore del testo chiaro :(
dhin

23

Nel mio caso, per l'icona e il titolo personalizzati questo ha funzionato (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)

1
l'ultima riga di quel codice ha funzionato perfettamente per me. Tutti gli altri suggerimenti non hanno funzionato, probabilmente perché i miei controller di visualizzazione sono tutti controllati da un controller di navigazione. In tal caso, il navigationController? è davvero richiesto.
Salx

Avrai bisogno delle prime quattro righe se desideri aggiungere un pulsante Indietro personalizzato. Altrimenti l'ultima riga ha funzionato.
Rafiqul Hasan

14

Ho risolto questo problema aggiungendo un "" al titolo StoryBoard del ViewController precedente. Solo uno spazio, non vuoto; D

inserisci qui la descrizione dell'immagine


Ho bisogno che la schermata precedente abbia un titolo, quindi immagino che non funzionerà per me.
lmiguelvargasf

2
Ho cancellato quel titolo ma il titolo sta ancora arrivando nel titolo del pulsante Indietro
Himali Shah,

1
non cancellare il titolo, il campo, inserire "" (spazio) nel campo del pulsante Indietro
Kiril S.

13

Finalmente ho trovato la soluzione perfetta.

Basta aggiungere un'immagine trasparente e aggiungere il seguente codice nel tuo AppDelegate.

UIBarButtonItem.appearance().setBackButtonBackgroundImage(#imageLiteral(resourceName: "transparent"), for: .normal, barMetrics: .default)

1
Questa è sicuramente la migliore risposta. In precedenza stavo usando l' UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustmenthack che la maggior parte delle altre risposte consiglia, ma era rotto su iPhone X per i controller di visualizzazione con titoli lunghi. Questa soluzione funziona perfettamente.
Ned

3
Migliore risposta. Ha funzionato meglio del colore del testo trasparente.
William T.

1
La migliore soluzione quella che ho usato negli ultimi 4 anni! Lo fai una volta, in un posto e per tutti i viewcontroller !!!
korgx9

1
Quando l'ho provato con iOS 12, il testo appariva ancora accanto all'immagine. :(
Sean McMains

13

in rapido 4

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

Grazie, mi ha aiutato, (Swift 4.0, Xcode 10.1, iOS 12.1.1), grazie
infinity_coding7

3
MA, perderai il tuo titolo in genitore vc
Wei Lu

1
Se è presente un titolo grande, topItem è largeTitle. Non funziona
Saranjith

10

Per Swift 4+ mettere queste linee in AppDelegateadidFinishLaunchingWithOptions

let BarButtonItemAppearance = UIBarButtonItem.appearance()

BarButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)      
BarButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)

Quando imposti l'aspetto nel delegato dell'app, il colore di primo piano chiaro è per ogni UIBarButtonItem, non è vero? Quindi, se aggiungo un UIBarButtonItem con un testo, devo modificare manualmente il colore di primo piano per questo pulsante?
kuzdu

1
Questo va bene, ma quando si preme il pulsante Indietro viene ancora visualizzato il testo
William T.

Funziona ma fa scomparire un altro pulsante della barra in iOS 11. La risposta di Rafiqul Hasan sopra può risolvere il problema
huync

8

Questo sta funzionando per me

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

Uno corretto. In iOS 13, navigationItem.backBarButtonItem non funziona. Mi ha risparmiato ore di lavoro. Grazie
Manish

5

Se si dispone di un ViewControllerA e si desidera passare al ViewControllerB, nel ViewControllerA, è necessario impostare il navigationItem corrente con un nuovo UIBarButtonItem e il titolo su una stringa con uno spazio vuoto prima di eseguire il push su un altro controller di visualizzazione:

Imposta il titolo su una stringa con uno spazio vuoto, non puoi impostare nil o "" (stringa vuota) perché il valore predefinito è nil

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

5

Metti questo codice in ogni VC che ne spinge un altro

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

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
}

3

Per rimuovere da tutti i viewcontroller in uno stack di controller di navigazione:

sottoclasse UINavigationController e aggiungi questo:

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)
}

2

A volte non funziona cambiare solo il colore del titolo, nel caso in cui il titolo sia lungo. Perché potrebbe spostare il titolo della barra di navigazione a sinistra. Quindi per prevenirlo potresti dover spostare il titolo del pulsante della barra orizzontalmente oltre a renderlo trasparente:

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

1

Per me questo ha funzionato:

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)
}

Si noti che se si imposta solo il titolo senza modificare l'backBarButtonItem sarà visualizzato al lavoro. Ma se provi a tornare indietro usando un gesto e poi annulla e rimani sul controller di visualizzazione premuto, il titolo precedente tornerà.

Lavorare in Swift 4


Potresti spiegare?
mrc

Ho un controller che mostra sempre il testo Indietro con il pulsante Indietro. Quindi il codice sopra non funziona nel mio caso
Shahbaz Akram

1

Selezionare la barra di navigazione del controller DA cui punta il pulsante Indietro e digitare "" nel campo Pulsante Indietro.

ad esempio, se stai spingendo un controller da un controller a un controller B, metti uno spazio vuoto nella barra di navigazione del controller A.


1

Xcode 10, Swift 4+

Risposta simile alle altre qui, ma vale la pena notare che se il testo non è ancora cancellato, devi fare clic su Spazio, quindi su Invio.

inserisci qui la descrizione dell'immagine


1

Dettagli

  • Xcode versione 10.2.1 (10E1001), Swift 5

Soluzione

1. Creare una classe personalizzata di 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. Aggiungere l'estensione UIViewController

import UIKit

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

3. Aggiorna la tua classe ViewController

import UIKit

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

Campione completo

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 }
}

Risultato

inserisci qui la descrizione dell'immagine


1

Un'alternativa per ignorare tutto ViewControllersper me era estendere UINavigationControllere impostare l' estensione backBarButtonItemdi topViewController.

Swift 5 su 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
    }
}

1

Il modo più semplice per eseguire questa operazione a livello di codice è impostare backBarButtonItemdal controller della visualizzazione padre (un controller che chiama push).

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

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

Maggiori dettagli qui https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/


1

È possibile rimuovere il testo dal pulsante Indietro utilizzando un metodo delegato di 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)
    }
    
}

0

In Xcode 9.2 con Swift, ha funzionato in questo modo:

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

0

Nel caso in cui non abbiamo affatto il controllo del controller di visualizzazione precedente (ovvero se stiamo lavorando in un framework), possiamo eliminare il titolo del pulsante Indietro come segue:

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

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

Quello che fa è passare all'ultimo elemento dello stack di navigazione ed eliminare il titolo precedente. Assicurati di salvare quello originale quando apparirà il nostro controller di visualizzazione:

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

e poi riassegnalo, in modo da non interrompere nessuna parte dell'app:

override func viewWillDisappear(_ animated: Bool) {
    navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = originalBackButtonTitle
    super.viewWillDisappear(animated)
}

0

Questo risolverà il tuo 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)

    }
}

0

Ho provato un paio di risposte e non riesco a farle funzionare in tutti i casi. Quindi questa è una soluzione alternativa per non influenzare il titolo della barra di navigazione se è impostata.

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

0

Il modo programmatico semplice, senza effetti collaterali indesiderati, è inizializzare il navigationItem.backBarButtonItem con un elemento vuoto nel metodo awakeFromNib del controller di origine (quello da cui stai navigando):

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

Nota: se hai inizializzato il pulsante Indietro in un secondo momento, come nel metodo viewDidLoad () , perderesti lo scorrimento all'indietro ( dal bordo sinistro a destra ti riporta indietro di un passo nello stack di navigazione).

Quindi, se desideri diversi testi del pulsante Indietro per diversi controller di destinazione e se stai usando segues, puoi impostare il titolo nel metodo di preparazione (per segue :, mittente :) , in questo modo:

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
        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.