Eliminar texto del botón Atrás manteniendo el icono

93

Quiero eliminar el texto del botón de retroceso, pero quiero mantener el icono. Yo he tratado

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

Sin embargo, esto elimina completamente el texto y el icono.

lmiguelvargasf
fuente

Respuestas:

98

El método de @ rmd2 es casi correcto, pero en su lugar debe seleccionar la barra de navegación del controlador al que apuntará " "el botón Atrás y escribir en el campo Botón Atrás.

ingrese la descripción de la imagen aquí

m8labs
fuente
1
de la peor manera, si el controlador de vista no tiene la barra de navegación, tendré que agregar para eliminar el texto
Daniel Beltrami
143

Sé que esto ya tiene una respuesta, pero también puede hacerlo en código (en caso de que esté trabajando con plumillas)

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

Agregue lo anterior en el primer controlador de vista.

Tenga en cuenta que debe hacer esto para cada controlador de vista que esté presionando. Entonces, si tiene 3 controladores de vista y desea eliminar el texto posterior de todos ellos, tendrá que agregar la línea en el controlador de vista 1 y 2.

d9rad
fuente
5
Esta es la mejor solución que he visto hasta ahora no me da problemas
lostAtSeaJoshua
4
.Plainfue cambiado a .plain. Sin mayúscula p.
Gal
Perfecto..! Eso es lo que quiero.
JD.
Mejor solución. Gracias.
Baran Emre
1
@ GastónAntonioMontes, que funciona en iOS13, pero es un contador de bits intuitivo: el título vacío backBarButtonItem debe ser declarada en la empujando controlador de vista, no el empujados uno
Martin
49

Después de buscar mucho, encontré la mejor y más simple solución, esto afectará a todos los viewControllers escritos en Swift 4.2 y que también funcionan en Swift 5

extension UIViewController {
    open override func awakeFromNib() {
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }  
}
iOS Lifee
fuente
Bienvenido @ e.dimitrow
iOS Lifee
1
Funciona a la perfección
Jerry Oka para
3
Tenga en cuenta que esto solo funcionará si su ViewController está contenido en un Storyboard o Nib ...
Nathaniel Blumer
1
¡Una solución genial!
WM
3
Esto solía funcionar para mí, pero ya no (todavía funciona en simuladores de iOS 12, pero no en el último iOS 13) ...
tanya
35

El texto del botón Atrás depende del título de la vista maestra.

El truco consiste en borrar el título si la vista maestra desaparece y volver a configurarlo si se vuelve a mostrar:

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
fuente
33

Si desea eliminar el título de un botón de retroceso de un controlador de vista empujado, digamos <Settingsque <en subSettingsViewController, entonces debe establecer el título backBarButtonItem en la vista de SettingsViewController () método .

C objetivo:

- (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
fuente
1
.Plainfue cambiado a .plain. Sin mayúscula p.
Gal
1
La respuesta debe actualizarse para el comportamiento de searchController. Por ejemplo, si usa un resultsVC separado y toca un elemento que empuja otro VC, no se llama al método viewWillDisappear del searchController inicial, por lo tanto, el título sigue ahí
H4Hugo
Este no es un buen enfoque si está buscando una solución para pantallas en toda la aplicación. - Si agrega este código a algún "Controlador de vista base", viewWillDisappear del primer controlador de vista se llamará después de viewDidAppear del segundo controlador de vista (donde normalmente establece el título) ... esto estropeará los títulos. La mejor manera es sobrescribir el botón de retroceso
Mithra Singam
Solución perfecta gracias
SURESH SANKE
28

Si desea la flecha hacia atrás, coloque el siguiente código en el archivo AppDelegate en el método didFinishLaunchingWithOptions.

Para Swift

let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)
Pradeep Bishnoi
fuente
2
me gusta este porque puede estandarizar el estilo de su aplicación en un solo archivo y llamarlo una vez desde el delegado de la aplicación
Aaronium112
4
Es una solución realmente agradable y rápida, pero ... podría ser complicado si tiene otros elementos de botón de barra excepto el de atrás
:)
3
Una observación, si solo implementa el atributo ".normal", verá el texto al hacer clic. Agregue la misma línea para ".selected", ".resaltado" y ".disabled". para asegurarse de que no vea el texto parpadeante.
Nick N
1
Creo que esto tendrá un efecto secundario, otros botones de la barra además de los botones de retroceso también se verán afectados y tendrán un color de texto claro :(
dhin
24

En mi caso, para el icono y el título personalizados, esto funcionó (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
fuente
1
la última línea de ese código funcionó perfectamente para mí. Todas las demás sugerencias no funcionaron, probablemente porque mis controladores de vista están controlados por un controlador de navegación. En cuyo caso, el navigationController? es realmente necesario.
Salx
Necesitará las cuatro líneas superiores si desea agregar un botón de retroceso personalizado. De lo contrario, la última línea funcionará.
Rafiqul Hasan
14

Resolví este problema agregando un "" en el título del StoryBoard del ViewController anterior. Solo un espacio, no vacío; D

ingrese la descripción de la imagen aquí

rmd2
fuente
Necesito que la pantalla anterior tenga un título, así que supongo que no me va a funcionar.
lmiguelvargasf
2
He dejado en blanco ese título, pero el título sigue
apareciendo en el
1
no deje en blanco el campo Título, ponga "" (espacio) en el campo Botón Atrás
Kiril S.
13

Finalmente encontré la solución perfecta.

Simplemente agregue una imagen transparente y agregue el siguiente código en su AppDelegate.

UIBarButtonItem.appearance().setBackButtonBackgroundImage(#imageLiteral(resourceName: "transparent"), for: .normal, barMetrics: .default)
Lalit Kumar
fuente
1
Esta es definitivamente la mejor respuesta. Anteriormente estaba usando el UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustmenttruco que recomiendan la mayoría de las otras respuestas, pero se rompió en el iPhone X para los controladores de vista con títulos largos. Esta solución funciona a la perfección.
Ned
3
La mejor respuesta. Funcionó mejor que el color de texto transparente.
William T.
1
¡La mejor solución que usé en los últimos 4 años! ¡Lo haces una vez, en un solo lugar y para todos los controladores de vista!
korgx9
1
Cuando probé esto con iOS 12, el texto seguía apareciendo junto a la imagen. :(
Sean McMains
13

en rápido 4

self.navigationController?.navigationBar.topItem?.title = ""
Amalendu Kar
fuente
Gracias, me ayudó (Swift 4.0, Xcode 10.1, iOS 12.1.1), gracias
infinity_coding7
3
PERO, perderá su título en el vc principal
Wei Lu
1
Si hay un título grande, topItem es largeTitle. No funciona
Saranjith
10

Para Swift 4+ poner estas líneas en AppDelegatealdidFinishLaunchingWithOptions

let BarButtonItemAppearance = UIBarButtonItem.appearance()

BarButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)      
BarButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)
BilalReffas
fuente
Cuando configura la apariencia en el delegado de la aplicación, el color de primer plano claro es para cada UIBarButtonItem, ¿no es así? Entonces, si agrego un UIBarButtonItem con un texto, ¿tengo que cambiar el color de primer plano para este botón manualmente?
kuzdu
1
Esto es bueno, pero cuando presiona el botón Atrás, todavía muestra el texto
William T.
Funciona, pero hace que el otro botón de la barra desaparezca en iOS 11. La respuesta de Rafiqul Hasan anterior puede solucionar el problema
huync
8

Esto es trabajo para mí

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
RomanV
fuente
Corriga uno. En ios 13, navigationItem.backBarButtonItem no funciona. Me ahorró horas de esfuerzos. Gracias
Manish
5

Si tiene un ViewControllerA y desea navegar hasta ViewControllerB, en ViewControllerA, debe configurar el navigationItem actual con un nuevo UIBarButtonItem y el título en una cadena con espacio en blanco antes de enviarlo a otro controlador de vista:

Establezca el título en una cadena con un espacio en blanco, no puede establecer nil o "" (cadena vacía) porque el valor predeterminado es nil

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

Pon este código en cada VC que empuja a otro

navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
Polina Hill
fuente
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
fuente
3

Para eliminar de todos los controladores de vista en una pila de controladores de navegación:

subclase UINavigationController y agregue esto:

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)
}
Gastón González
fuente
2

A veces no funciona cambiar solo el color del título, en caso de que el título sea largo. Porque podría desplazar el título de la barra de navegación hacia la izquierda. Entonces, para evitarlo, es posible que deba cambiar el título del botón de la barra horizontalmente además de hacerlo transparente:

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

Detalles

  • Versión de Xcode 10.2.1 (10E1001), Swift 5

Solución

1. Cree una clase personalizada de 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. Agregue la extensión UIViewController

import UIKit

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

3. Actualice su clase ViewController

import UIKit

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

Muestra 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

ingrese la descripción de la imagen aquí

Vasily Bodnarchuk
fuente
1

Para mí, esto funcionó:

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

Tenga en cuenta que si solo establece el título sin modificar el backBarButtonItem, parecerá que funciona. Pero si intenta regresar usando un gesto y luego cancela y permanece en el controlador de vista empujado, el título anterior volverá.

Trabajar en Swift 4

mrc
fuente
¿Podrías explicar?
mrc
Tengo un controlador que siempre muestra el texto Atrás con el botón Atrás. Entonces, el código anterior no funciona en mi caso
Shahbaz Akram
1

Debe seleccionar la barra de navegación del controlador DESDE el botón de retroceso al que apuntará y escribir "" en el campo Botón de retroceso.

Por ejemplo, si está presionando el controlador A al controlador B, coloque un espacio en blanco en la barra de navegación del controlador A.

Tushar Raikwar
fuente
1

Xcode 10, Swift 4+

Respuesta similar a las otras aquí, pero vale la pena señalar que si el texto aún no se borra, debe hacer clic en Espacio y luego en Entrar.

ingrese la descripción de la imagen aquí

Aishat Olowoshile
fuente
1

Una alternativa para anular todo ViewControllerspara mí era extender UINavigationControllery configurar backBarButtonItemel topViewController.

Swift 5 en 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
    }
}
Desafortunado
fuente
1

La forma más sencilla de hacer esto mediante programación es establecer backBarButtonItemdesde el controlador de vista principal (un controlador que llama a push).

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

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

Más detalles aquí https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/

sarunw
fuente
1

Puede eliminar texto del botón Atrás mediante un método delegado 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
fuente
0

En Xcode 9.2 con Swift, funcionó así:

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

Para el caso en el que no tenemos control en absoluto del controlador de vista anterior (es decir, si estamos trabajando en un marco), podemos eliminar el título del botón de retroceso de la siguiente manera:

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

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

Lo que hace es navegar hasta el último elemento de la pila de navegación y eliminar su título anterior. Asegúrese de guardar el original cuando aparezca nuestro controlador de vista:

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

y luego reasignarlo, para no interrumpir ninguna parte de la aplicación:

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

Esto solucionará su 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
fuente
0

Probé un par de respuestas y no puedo hacer que funcionen en todos los casos. Entonces, esta es una solución para no afectar el título de la barra de navegación si está configurada.

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

La forma sencilla de programación, sin efectos secundarios no deseados, es inicializar navigationItem.backBarButtonItem con un elemento vacío en el método awakeFromNib del controlador de origen (desde el que está navegando):

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

Nota: Si inicializara el botón de retroceso más tarde, como en el método viewDidLoad () , perdería la funcionalidad de deslizar hacia atrás ( deslizar el dedo desde el borde izquierdo hacia la derecha lo lleva un paso hacia atrás en la pila de navegación).

Luego, si desea diferentes textos de botón de retroceso para diferentes controladores de destino y si está usando segues, puede establecer el título en el método prepare (for segue :, sender :) , así:

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
fuente