Cómo eliminar todo el título del botón de retroceso de la barra de navegación

81

Cuando presiono a UIViewController, tiene un título en el botón de retroceso en nuevo UIViewController, si el título tiene mucho texto, no se ve bien en el iPhone 4s, así que quiero eliminarlo.

Si agrego algún código en prepareForSeguefunción, será un problema.

Cualquier mejor forma de lograr esto?

jansma
fuente
también puede cambiar el título del botón Atrás. y para volver se requiere el botón Atrás. así que creo que no es necesario quitar el botón de retroceso.
Ashok Londhe
Informe después de resolver su problema.
Ashok Londhe
consulte esta respuesta stackoverflow.com/a/48801613/3976183
Lalit Kumar
hay un buen artículo sobre este tema sarunw.com/posts/…
user3672430

Respuestas:

128

Si desea la flecha hacia atrás, coloque el siguiente código en el AppDelegatearchivo en el didFinishLaunchingWithOptionsmétodo.

For Objective-C

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

For Swift

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

Otra opción da a continuación.

En Objective C

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

En Swift

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

ACTUALIZAR:

    let BarButtonItemAppearance = UIBarButtonItem.appearance()

    let attributes: [NSAttributedStringKey: Any] = [
    BarButtonItemAppearance.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)
            NSAttributedStringKey.font: UIFont.systemFont(ofSize: 0.1),
            NSAttributedStringKey.foregroundColor: UIColor.clear]

    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .normal)
    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .highlighted)

ACTUALIZAR SWIFT 4.1:

    let attributes = [NSAttributedStringKey.font:  UIFont(name: "Helvetica-Bold", size: 0.1)!, NSAttributedStringKey.foregroundColor: UIColor.clear]

    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .normal)
    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .highlighted)

Uso de compensación

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(-1000, 0), for:UIBarMetrics.default)

Entonces puede ser que su problema haya sido resuelto.

Codificación feliz.

Nimit Parekh
fuente
8
setBackButtonTitlePositionAdjustmentno siempre funciona, cuando el título del botón Atrás es muy largo, pero no lo suficiente para cambiar a "Atrás", el título del medio se moverá hacia la derecha.
zgjie
3
@zgjie es solo un tema de cuán grande es su compensación. puede reemplazar fácilmente '-60' con '-6000' y olvidarse de este problema
slxl
9
Solo un poco de precisión aquí, el título pertenece al controlador de vista ANTERIOR. Así que recuerde colocarlo allí, antes del método presentViewController o pushViewController.
Benjamin
1
Hmm, esto no funciona en AppDelegate. "El valor de tipo AppDelegate no tiene miembro navigationItem"
Prabhu
3
@DominikBucher He creado una categoría para este comportamiento que oculta el título del botón de retroceso en todas partes de la aplicación, lo cual es un poco "NON HACKY" , simplemente agregue la categoría en su proyecto y listo. Estoy totalmente en desacuerdo con la solución de configurar la posición usando setBackButtonTitlePositionAdjustment:forBarMetrics:si el usuario ha habilitado la forma del botón desde la configuración de accesibilidad, la forma aparecerá terminando en una barra de navegación fea.
Pratik Jamariya
71

Trabajar es como un encanto en Swift 3

self.navigationController?.navigationBar.topItem?.title = " "
Mahesh Babu
fuente
1
Este es el único que funcionó al usarnavigationController?.pushViewController(_, animated:)
D. Greg
Gracias amigo. Este fue el único que funcionó. Salud.
Felipe
3
También funcionó para mí Swift 4
christijk
1
@MaksimKniazev, ¿alguna solución para ese problema? Encontré la única solución para actualizar el título nuevamente en viewWillAppear:.
Hemang
4
esto elimina el título de la vista anterior
Naser Mohamed
50

Estoy usando esta línea de código en el AppDelegatearchivo en el didFinishLaunchingWithOptionsmétodo para eliminar el botón trasero title.

Rápido 2.x

let barAppearace = UIBarButtonItem.appearance()
barAppearace.setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics:UIBarMetrics.Default)

Swift 3.x

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), for:UIBarMetrics.default)

Swift 4.x

UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
    UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: UIControlState.highlighted)
Karthickkck
fuente
17
setBackButtonTitlePositionAdjustmentno siempre funciona, cuando el título del botón Atrás es muy largo, pero no lo suficiente para cambiar a "Atrás", el título del medio se moverá hacia la derecha.
zgjie
No es una solución ideal. Si configuramos cualquier título de navegación sin cambiar el título del elemento de la barra de navegación izquierda, el título se desplazará hacia la derecha debido a que tiene inserciones de título en la barra de navegación izquierda.
mathema
2
en iOS 11 se rompe la posición del botón de retroceso. Está por debajo de su posición original
korgx9
¿Cómo se supone que funciona? El texto seguirá siendo accesible a través de VoiceOver.
Lukasz Ciastko
Esto crea un problema cuando el elemento de botón de barra cancelado o terminado no son visibles al presentar el selector de imágenes o algo así
Nupur Sharma
16

Solo tiene que ir a su ViewController principal de donde dependen sus otros ViewControllers.

override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(true)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)}
Pravin Kamble
fuente
15

Simplemente copie este código en didFinishLaunchingWithOptions launchOptions

Rápido 5

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: -1000.0, vertical: 0.0), for: .default)

Rápido 4

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(-1000.0, 0.0), for: .default)
Vivek
fuente
11

Es simple. pon un espacio en el título del botón de retroceso y listo. Recuerda que tiene que estar en la vista anterior donde quieres eliminar el texto.

ingrese la descripción de la imagen aquí

oscar castellon
fuente
La mejor solución en mi opinión. No requiere que configure toda la aplicación con un estilo claro específico que puede tener el efecto secundario de hacer desaparecer cualquier elemento de botón de barra de texto. La respuesta podría mejorarse si mencionara que tiene que arrastrar un elemento de navegación a su controlador si no hay uno allí.
TheJeff
7

Puede usar xcode 8 y swift 3.0

self.navigationController?.navigationBar.backItem?.title = " "
Anit Kumar
fuente
3
¿No eliminará esto el título del controlador de vista anterior por completo?
NRitH
1
Sí, eliminará el título de todos ViewControllerlos self.navigationController
mensajes enviados
7

Puede crear una subclase para todos los UIViewControllers para los que desea este comportamiento, y en la subclase viewDidLoad:

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

De esta manera, puede elegir para qué controladores desea el comportamiento, sin duplicar el código. Prefiero que mis controladores simplemente digan "Atrás", en lugar del título del controlador anterior, así que establezco ese título aquí.

Connor
fuente
6
let barAppearace = UIBarButtonItem.appearance()
barAppearace.setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), for:UIBarMetrics.default)

usé esta línea de código en swift 3.0

Kiran jadhav
fuente
1
afectará el botón cancelar para UISearchController
JAHelia
5

Inspirándome en la respuesta de rordulu aquí , terminé creando un UINavigationController personalizado y una barra de UINavigation que parece manejar todos los casos de este complicado problema.

1) Inicialice nuevo UINavigationControllercon su personalizado UINavigationBar:

class CustomNavigationController: UINavigationController {

    convenience init() {
        self.init(navigationBarClass: CustomNavigationBar.self, toolbarClass: nil)
    }
}

2) Establezca la backItem.titlepropiedad de la barra de navegación en una cadena vacía, cada vez que la vista se muestre

class CustomNavigationBar: UINavigationBar {

    override func layoutSubviews() {
        backItem?.title = ""
        super.layoutSubviews()
    }
}

Ahora, cada vez que use esta combinación de barra y controlador de navegación, ¡nunca tendrá el texto del botón de retroceso! 🎉

Nota: esto debería funcionar bien si también usa guiones gráficos, solo asegúrese de colocar el componente de la barra de navegación personalizada en la vista

Harry Bloom
fuente
¡Increíble, muchas gracias! Esta es la mejor manera de hacerlo y debería ser la respuesta correcta :)
GameDev
3
Me acabo de dar cuenta de que esto tiene un efecto secundario, ya que borrará completamente el título del elemento de navegación. Entonces, cuando se muestre la vista anterior, ¡no tendrá un título! Continuaré mi búsqueda de la solución perfecta a este molesto problema.
Harry Bloom
maldita sea, tienes razón. ¡Cómo podría perderme eso! Por favor dígame si encuentra una solución a este problema. gracias
GameDev
¿Podrías encontrar la solución perfecta @HarryBloom?
Hemang
@Hemang No es una solución perfecta, pero encontré algo que funciona. He agregado una segunda respuesta aquí stackoverflow.com/a/49094282/1532838
Harry Bloom
3

Por lo general, agrego o cambio el botón Atrás en viewDidLoad de UIViewController.

Algo así debería funcionar:

let leftButton = UIBarButtonItem(title: "Back", style:     UIBarButtonItemStyle.Plain, target: self, action: "closeView:")
self.navigationItem.leftBarButtonItem = leftButton

No olvide cambiar e implementar la función a la que se llama para cerrar la vista.

Aún más fácil, simplemente cambie el título:

self.navigationItem.leftBarButtonItem.title = "Back"
pteofil
fuente
7
Esto rompe el soporte incorporado de iOS para deslizar de izquierda a derecha para navegar hacia atrás, y en mi humilde opinión, las aplicaciones que rompen esto son realmente irritantes.
NRitH
2

Swift 3:

self.navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style:.plain, target:nil, action:nil)
Ahmed Safadi
fuente
2

Agregar una segunda respuesta aquí como la primera solo funciona parcialmente. Este método es menos elegante en el hecho de que requiere llamar a un método en cada vista de la aplicación, sin embargo, funciona sin efectos secundarios.

Entonces, en primer lugar, cree una clase de extensión UIViewController con una función para eliminar el texto del botón de retroceso y agregar un botón de retroceso personalizado:

extension UIViewController {

func setBackButton() {
    navigationController?.navigationBar.backIndicatorImage = R.image.backArrow()
    navigationController?.navigationBar.backIndicatorTransitionMaskImage = R.image.backArrow()
    navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}

En segundo lugar, simplemente podemos llamar a esta función en viewDidLoadcada controlador de vista en el que lo necesite.

Harry Bloom
fuente
2

Solución simple :

Mientras presiona el segundo controlador desde el primer controlador, coloque self.navigationItem.title = "" en viewWillDisappear del primer controlador. Oculta el título del botón de retroceso del segundo controlador.

La declaración anterior oculta el título del primer controlador, por lo tanto, cuando regresamos, queremos el título del primer controlador nuevamente. Para eso hemos agregado el título para el primer controlador en el método viewWillAppear del primer controlador.

Consulte los siguientes métodos (del primer controlador)

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

override func viewWillAppear(_ animated: Bool) {
    self.navigationItem.title = "Title"
}
Mayur Shinde
fuente
2

Rápido 4.2

UIBarButtonItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)
Abhishek Jain
fuente
Los botones Cancelar y Listo del selector de imágenes desaparecen en este enfoque
Nupur Sharma
2

Respuesta actualizada para Swift 4.2

Trabajar con UIAppearancees una forma más limpia de resolver el problema, pero haría que todos UIBarButtonItemtuvieran un texto claro. Una versión mejorada de la solución podría ser verificar si UIBarButtonItemestá contenido en un UINavigationBar.

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal)
Md. Ibrahim Hassan
fuente
1

Funciona en Swift 5 :

        self.navigationItem.backBarButtonItem?.title = ""

Tenga en cuenta que será efectivo para el próximo controlador de vista empujado, no el actual en la pantalla, ¡por eso es muy confuso!

Además, verifique el guión gráfico y seleccione el elemento de navegación del controlador de vista anterior , luego escriba algo en el Botón Atrás (Inspector).

Saeed Ir
fuente
1

Tengo una solución simple para aquellos que no quieren usar el método swizzling o duplicar un código similar en diferentes controladores de vista.

Para eliminar el título del botón Atrás, cree una subclase UINavigationController y anule el método pushViewController (_, animated :):

final class CustomNavigationController: UINavigationController {

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {

        super.pushViewController(viewController, animated: animated)

        let backBarButtonItem = UIBarButtonItem()
        backBarButtonItem.title = nil

        viewController.navigationItem.backBarButtonItem = backBarButtonItem
    }
}
Nikita Teplyakov
fuente
0

No sé por qué, pero encontré un problema al ocultar el título del botón Atrás en las ventajas del iPhone, pero en el dispositivo sin el signo más se muestra correcto con

leftBarButtonItem.title = ""

Así que encontré una forma sencilla. Se establece el color del tinte para borrar en NavigationBar de NavigationViewController en el diseño automático. Puede ser un problema si utiliza iconos o mosaicos de texto con tinte. Pero en mi caso no lo uso como todo.

Vasily Avilov
fuente
0

Solo usa esto:

func removeBackButton(vc:UIViewController) {
        let button = UIButton.init(type: .custom)
        button.setImage(UIImage.init(named:""), for: .normal)
        let leftBarButton = UIBarButtonItem.init(customView: button)
        vc.navigationItem.leftBarButtonItem = leftBarButton
}

Así que llama a este método en viewDidLoad:

override func viewDidLoad() {
        super.viewDidLoad()
     removeBackButton(vc:self)
}
reza_khalafi
fuente
0

Puede agregar esta extensión a UIViewController y luego llamar a esta función en cada viewDidLoad () como: self.updateBackButton ()

extension UIViewController {
func updateBackButton(){
    if self.navigationController != nil {
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .done, target: self, action: nil)
    }
}}
Talha Ahmad Khan
fuente
0

Me gustaría compartir una solución que funcione para mí. Además, se puede ajustar en función de sus necesidades y requisitos.

Tenga en cuenta que, en mi caso, uso un guión gráfico para especificar CustomNavigationBar

Rápido 4.2

class CustomNavigationBar: UINavigationBar {

    override func awakeFromNib() {
        super.awakeFromNib()
        guard let topItem = topItem else { return }
        removeBackButtonTitle(for: topItem)
    }

    override func pushItem(_ item: UINavigationItem, animated: Bool) {
        removeBackButtonTitle(for: item)
        super.pushItem(item, animated: animated)
    }

    func removeBackButtonTitle(for item: UINavigationItem) {
        item.backBarButtonItem = UIBarButtonItem()
    }
}
ixi
fuente
0

Funciona para Swift 4.2

Usando la línea de código en el AppDelegatearchivo endidFinishLaunchingWithOptions

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal)

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .highlighted)
veradiego31
fuente
Esto oculta el texto del botón de la barra de retroceso, pero desafortunadamente no centra el título de la barra de navegación
Giorgio
0

Swift 4.2 y 5

En lugar de jugar con el color de tinte de la barra de navegación, tendrá efectos secundarios si está utilizando el selector de imágenes en cualquier momento más adelante en su código.

Utilice el siguiente código:

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

Llámelo desde su primer ViewController:

self.awakeFromNib()
Md Rais
fuente
0

para rápido 4,5

let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)
Sargis
fuente
0

Simplemente cree la extensión de UIViewControllercon la función de anulación awakeFromNib()y haga UIBarButtonItemcon un título vacío y dé a navigation backBarButtonItem.

extension UIViewController {

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

}
Ashish
fuente
0

Coloque el siguiente código en cualquiera de los UIViewcontroller extensionque ocultará todo el UIViewcontrollertexto posterior

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

en viewDidLoad()

    let backBarButtonItem = UIBarButtonItem(title: nil, style: .plain, target: nil, action: nil)
    navigationItem.backBarButtonItem = backBarButtonItem
Yura
fuente
0

He encontrado una solución simple: -

en el PersingtingViewController's viewWillDisappearmétodo jsut poner

self.title = ""

y establecer titlepara PersingtingViewController'sel viewWillAppearmétodo. Y repetir esta operación para todos los viewControllersde navigationStacka excepción de la última.

Ravi Sharma
fuente
0

En iOS 14 ahora está presente la backButtonDisplayModepropiedad en UINavigationItemclase. Entonces, para eliminar el título del botón de retroceso, puede usar

navigationItem.backButtonDisplayMode = .minimal

en la viewDidLoadfunción del viewController donde desea eliminarlo.

Para eliminarlo en toda la barra de navegación utilicé la técnica swizzling

import UIKit

private let swizzling: (UIViewController.Type, Selector, Selector) -> Void = { forClass, originalSelector, swizzledSelector in
    if let originalMethod = class_getInstanceMethod(forClass, originalSelector), let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector) {
        let didAddMethod = class_addMethod(forClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
        if didAddMethod {
            class_replaceMethod(forClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

extension UIViewController {
    
    static func swizzle() {
        let originalSelector1 = #selector(viewDidLoad)
        let swizzledSelector1 = #selector(swizzled_viewDidLoad)
        swizzling(UIViewController.self, originalSelector1, swizzledSelector1)
    }
    
    @objc open func swizzled_viewDidLoad() {
        if let _ = navigationController {
            if #available(iOS 14.0, *) {
                navigationItem.backButtonDisplayMode = .minimal
            } else {
                // Fallback on earlier versions
                navigationItem.backButtonTitle = ""
            }
        }
        swizzled_viewDidLoad()
    }
}

Y en application(_:didFinishLaunchingWithOptions:)llamada

UIViewController.swizzle()
Giorgio
fuente