UINavigationBar Ocultar el texto del botón de retroceso


104

¿Cómo puedo ocultar el texto del botón Atrás de un controlador de navegación UIN? Solo tendré el "<" y no el "<Atrás"


1
no puede modificar el texto predeterminado, en su lugar, intente navigationItem.leftBarButtonItem para configurar el botón de retroceso personalizado
BaSha


Vea mi respuesta a continuación, si desea una solución global que utilice un proxy de apariencia.
fl034

Respuestas:


107

En el generador de interfaz , puede seleccionar el elemento de navegación del controlador anterior y cambiar la Back Buttoncadena a la que le gustaría que aparezca el botón Atrás. Si lo quiere en blanco, por ejemplo, simplemente ponga un espacio.

También puede cambiarlo con esta línea de código:

[self.navigationItem.backBarButtonItem setTitle:@"Title here"];

O en Swift :

self.navigationItem.backBarButtonItem?.title = ""


2
Consejo impresionante, el de establecer un espacio vacío en el constructor de interfaces ... :-D
Felipe Ferri

9
El constructor de interfaces y las rutas programáticas Swift no me funcionaron en XCode 8.3.2, Swift 3
agrippa

Puede consultar mi solución muy simple para ocultar todos los botones de retroceso en la aplicación. PD: Requiere cero línea de código propio
Pratik Jamariya

2
Si Back Buttonya está en blanco en IB, simplemente agregue un espacio para viajar Backy muestre la flecha.
Tejas K

3
Este método actualmente solo funciona en el generador de interfaces. Establecer esto desde el código no funciona, en lugar de establecer solo el título, necesita establecer todo el backBarButtonItem de esta manera: navigationItem.backBarButtonItem = UIBarButtonItem (título: "", estilo: .plain, destino: nulo, acción: nulo)
Leszek Szary

81

También puede hacer esto a través del guión gráfico. En el inspector de atributos del elemento de navegación del controlador anterior , puede establecer "" en el campo del botón Atrás. Consulte la imagen a continuación. Reemplaza "Tu título aquí" por "". Al hacer esto, logrará el resultado deseado. Ya no necesita meterse con el 'Título'.

Programáticamente podrías usar

[self.navigationItem.backBarButtonItem setTitle:@" "];

donde self se refiere al controlador que presiona el controlador de vista deseado.

Elemento de navegación del controlador de vista Xcode

Muestra antes, después de la barra de navegación

antes de antes de

Después Después


7
Esto funciona perfectamente si se establece en guiones gráficos. Solo asegúrese de que la barra de navegación tenga un elemento de navegación para que pueda configurarse.

11
En iOS 9 / Xcode 7.3, la configuración backBarButtonItemprogramática no funciona, pero la configuración a través del guión gráfico sí.
Scott Gardner

@ScottGardner, la configuración me funcionabackBarButtonItem programáticamente en iOS 9.
Suragch

Si no tiene una barra de navegación en su pantalla, tal vez porque necesita estar oculta, puede agregar un elemento de navegación en el guión gráfico, al controlador de vista anterior y establecer su botón de retroceso en "".
Martin Berger

La solución funcionó muy bien y es muy fácil de implementar en Xcode 9.2 / iOS 11.
Ray Hunter

78

Puedes implementar UINavigationControllerDelegateasí:

Swift mayor

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
    let item = UIBarButtonItem(title: " ", style: .Plain, target: nil, action: nil)
    viewController.navigationItem.backBarButtonItem = item
}

Swift 4.x

class MyNavigationController: UINavigationController, UINavigationControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        let item = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
        viewController.navigationItem.backBarButtonItem = item
    }
}

backBarButtonItemes nilpor defecto y afecta al siguiente controlador empujado, por lo que simplemente lo configura para todos los controladores


6
¡Gracias! Esta es la única solución que funcionó (sin estropear nada más) después de mirar 4 preguntas duplicadas y docenas de respuestas.
Entrada

1
Ya tenía una subclase de controlador de navegación que convertí en su propio delegado, esto funcionó perfectamente. Sin embargo, debería actualizarse para Swift 3.
Dean Kelly

Gran solución gracias, la única que funcionó consistentemente para mí.
Elliott Davies

Funciona como un encanto.
tounaobun

46

Establecer el título del botón de retroceso en @""o nilno funcionará. Debe dejar todo el botón vacío (sin título o imagen):

C objetivo

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

Rápido

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

Esto debe hacerse en el controlador de vista que está en la parte superior de su controlador de vista en la pila de navegación (es decir, desde donde navega a su VC a través del pushViewControllermétodo)


2
gracias, funciona! En rápido: self.navigationItem.backBarButtonItem = UIBarButtonItem (título: "", estilo: .Plain, objetivo: nulo, acción: nulo)
mostworld77

30

Otra solución a este problema para situaciones en las que tiene una gran cantidad de controladores de vista es usar un UIAppearanceproxy para ocultar efectivamente el texto del título del botón Atrás como este:

UIBarButtonItem *navBarButtonAppearance = [UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil];

[navBarButtonAppearance setTitleTextAttributes:@{
    NSFontAttributeName:            [UIFont systemFontOfSize:0.1],
    NSForegroundColorAttributeName: [UIColor clearColor] }
                                      forState:UIControlStateNormal];

Esta solución representará el texto como un pequeño punto claro, similar a configurar manualmente el título del botón Atrás @" ", excepto que afecta a todos los botones de la barra de navegación.

No sugiero esto como una solución general al problema porque afecta a todos los botones de la barra de navegación. Cambia el paradigma para que usted elija cuándo mostrar los títulos de los botones, en lugar de cuándo ocultar los títulos.

Para elegir cuándo mostrar los títulos, restaure manualmente los atributos del texto del título según sea necesario o cree una subclase especializada UIBarButtonItemque haga lo mismo (potencialmente con otro UIAppearanceproxy).

Si tiene una aplicación en la que la mayoría de los títulos del botón de retroceso deben estar ocultos, y solo algunos (o ninguno) de los botones de navegación son botones del sistema con títulos, ¡esto podría ser para usted!

(Nota: es necesario cambiar el tamaño de la fuente aunque el color del texto sea claro para garantizar que los títulos largos no hagan que el título de la barra de navegación central se mueva)


Fue la solución más sencilla para mi implementación. Gracias.
Trevor Panhorst

3
¿No cubre esto también los elementos del botón de la barra izquierda que no son botones de retroceso?
Kevinl

1
Sí, lo noté mucho. "Afecta a todos los botones de la barra de navegación"
Adam Kaplan

2
¿No debería afectar a todos los demás botones de las barras de navegación, incluidos los elementos de los botones de la barra izquierda / derecha?
Fyodor Volchyok

Sí, no especificó un requisito más completo.
Adam Kaplan

30

Agregue el siguiente código en viewDidLoad o loadView

self.navigationController.navigationBar.topItem.title = @"";  

Lo probé en iPhone y iPad con iOS 9


20
¿Esto no borró el título del controlador de vista anterior?
CalZone

6
No utilice porque va a eliminar el último título de la pantalla
evya

Si necesita hacerlo desde el controlador de vista actual, para evitar eliminar el título de la vc anterior, debería hacer: navigationController? .NavigationBar.topItem? .BackBarButtonItem = UIBarButtonItem (title: "", style: .plain, target: nil, acción: cero)
Leszek Szary

15

Puede agregar esta categoría Objective-C para que todos los botones "Atrás" creados por un controlador de navegación no tengan texto. Lo acabo de agregar a mi archivo AppDelegate.m.

@implementation UINavigationItem (Customization)

/**
 Removes text from all default back buttons so only the arrow or custom image shows up.
 */
-(UIBarButtonItem *)backBarButtonItem
{
    return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}

@end

PD: (no sé cómo hacer que esta extensión funcione con Swift, estaba teniendo errores extraños. Las ediciones son bienvenidas para agregar una versión Swift)


Esto da el título de "Volver" no ocultar el título
Raj Aggrawal

Realmente, cómo overridehacerlo en rápido. Pregunta muy interesante
Andrey Gagan

@teradyl es la mejor respuesta.
aks.knit1108

@Andrey Gagan, vea mi respuesta
Abirami Bala

Esto funciona en iOS 9.0 - 10.3.3, pero en iOS 11+ no funciona.
Sihad Begovic

14

Probé algunos arriba y abajo pero no funcionaron. Esto funcionó para mí:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.topItem?.title = ""
}

1
Si necesita hacerlo desde el controlador de vista actual, para evitar eliminar el título de la vc anterior, debería hacerlo: navigationController? .NavigationBar.topItem? .BackBarButtonItem = UIBarButtonItem (title: "", style: .plain, target: nil, acción: nula)
Leszek Szary

11

Lo único que funciona sin efectos secundarios es crear un botón de retroceso personalizado. Siempre que no proporcione una acción personalizada, incluso el gesto de deslizar funciona.

extension UIViewController {
func setupBackButton() {
    let customBackButton = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
    navigationItem.backBarButtonItem = customBackButton
}}

Desafortunadamente, si desea que todos los botones de retroceso no tengan ningún título, debe configurar este botón de retroceso personalizado en todos sus controladores de vista: /

override func viewDidLoad() {
    super.viewDidLoad()

    setupBackButton()
}

Es muy importante que establezca un espacio en blanco como título y no como cadena vacía.


9

para eliminar el texto del botón de fondo mediante programación, se usa debajo del código, esto funcionará desde xcode7 y superior.

self.navigationController.navigationBar.topItem.title = @ "";

o

manualLy en los guiones gráficos, seleccione la barra de navegación en el controlador de vista y coloque "" en el texto del botón de retroceso.

esto funcionará. Gracias


2
Este también eliminará el título del elemento de navegación
Ilker Baltaci

Edité tu respuesta a esto: ¡ self.navigationController?.navigationBar.topItem?.title = " "en Xcode 9 y trabajé!
MHSFisher

Si necesita hacerlo desde el controlador de vista actual, para evitar eliminar el título de la vc anterior, debería hacer: navigationController? .NavigationBar.topItem? .BackBarButtonItem = UIBarButtonItem (title: "", style: .plain, target: nil, acción: nula)
Leszek Szary

8

La respuesta actual no estaba funcionando. Quería eliminar el título por completo, pero el texto "atrás" no desaparecía.

Regrese al controlador de vista anterior y establezca su propiedad de título:

self.title = @" ";

SOLO funciona cuando el controlador de vista anterior no tiene un título


@ZevEisenberg asegúrese de que la propiedad se establezca antes de que se muestre en el ciclo de vida del controlador de vista. Es decir, configúrelo en los métodos viewDidLoad o viewWillAppear.
ChrisHaze

1
Además, asegúrese de incluir un espacio entre las comillas.
ChrisHaze

1
De hecho, terminó funcionando para mí sin espacios; sólo una buena vieja cadena vacía: @"".
Zev Eisenberg

1
@ZevEisenberg, cuando se me ocurrió la solución por primera vez, estaba en Xcode 5. Con un espacio era la única forma en que funcionaba, por eso lo incluí en el código de muestra. La actualización de Xcode 6 debe haberlo incluido. Es bueno saberlo - gracias
ChrisHaze

También utilicé mi enfoque, que todavía funciona, y de hecho también eliminé la flecha hacia atrás estándar.
ChrisHaze

5

Manera alternativa: use la clase NavigationBar personalizada.

class NavigationBar: UINavigationBar {

    var hideBackItem = true
    private let emptyTitle = ""

    override func layoutSubviews() {
        if let `topItem` = topItem,
            topItem.backBarButtonItem?.title != emptyTitle,
            hideBackItem {
            topItem.backBarButtonItem = UIBarButtonItem(title: emptyTitle, style: .plain, target: nil, action: nil)
        }

        super.layoutSubviews()
    }

}

Es decir, esto elimina los títulos de todo el proyecto. Simplemente configure una clase personalizada para UINavigationController.


4

Establezca el título del VC anterior en "" cadena con espacio. y el título con el botón Atrás se reemplazará con una cadena de un solo espacio.

Self.title = " "

En Atrás presione nuevamente para restablecer el título al original en la vista.


4

Utilice una costumbre NavigationControllerque anulepushViewController

class NavigationController: UINavigationController {  
  override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    viewController.navigationItem.backBarButtonItem =
      UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    super.pushViewController(viewController, animated: animated)
  }
}

4

Ya tengo muchas respuestas, aquí están mis dos centavos sobre el tema. Encontré este enfoque realmente sólido. Solo necesita poner esto en viewController antes de segue.

Rápido 4:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

2
¡Si! Gracias :)
Hews

3

Probé todo en esta publicación. La única solución que funciona es @ VoidLess's

Aquí tienes la misma respuesta pero más completa.

class CustomNavigationController: UINavigationController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.delegate = self
    }
}


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

3

Esta es mi resolución para iOS11, cambio la apariencia de UIBarButtonItem en applicationDidFinishLaunchingWithOptions:

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

No puede cambiar el desplazamiento Y, porque también cambiará la posición del botón de la barra trasera en iOS11, pero está bien en iOS10 y versiones inferiores.


1
Funciona, pero durante la animación puede ver el título anterior moviéndose a la izquierda. Parece un poco con errores.
Jonathan

2

En Swift3,

Si establece la configuración global

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // ..

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


    // ...

}

1
Tenga en cuenta que esto también cambiará el color a transparente para todos los demás botones de la barra que pueda tener en algún lugar de su aplicación, no solo los botones de retroceso.
Leszek Szary

2

Swift 3.1 Puede hacer esto implementando el método delegado de UINavigationController.

func navigationController(_ navigationController: UINavigationController, 
                          willShow viewController: UIViewController, animated: Bool) {

    /** It'll hide the Title with back button only,
     ** we'll still get the back arrow image and default functionality.
     */
    let item = UIBarButtonItem(title: " ", style: .plain, target: nil, 
                               action: nil)
    viewController.navigationItem.backBarButtonItem = item
}

¡La mejor respuesta!
evya

2

Para aquellos que quieren ocultar el título del botón de retroceso a nivel mundial.

Puede swizzle viewDidLoadde UIViewControlleresta manera.

+ (void)overrideBackButtonTitle {

    NSError *error;

    // I use `Aspects` for easier swizzling.

    [UIViewController aspect_hookSelector:@selector(viewDidLoad)
                              withOptions:AspectPositionBefore
                               usingBlock:^(id<AspectInfo> aspectInfo)
    {

        UIViewController *vc = (UIViewController *)aspectInfo.instance;

        // Check whether this class is my app's view controller or not.
        // We don't want to override this for Apple's view controllers,
        // or view controllers from external framework.

        NSString *className = NSStringFromClass([vc class]);
        Class class = [NSBundle.mainBundle classNamed:className];
        if (!class) {
           return;
        }

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

    } error:&error];

    if (error) {
        NSLog(@"%s error: %@", __FUNCTION__, error.localizedDescription);
    }

}

Uso:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[self class] overrideBackButtonTitle];
    return YES;
}

2

Si tiene como objetivo iOS 13 y versiones posteriores, puede usar esta nueva API para ocultar el título del botón Atrás a nivel mundial .

let backButtonAppearance = UIBarButtonItemAppearance()
backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]

UINavigationBar.appearance().standardAppearance.backButtonAppearance = backButtonAppearance
UINavigationBar.appearance().compactAppearance.backButtonAppearance = backButtonAppearance
UINavigationBar.appearance().scrollEdgeAppearance.backButtonAppearance = backButtonAppearance

1
Esto no es óptimo. Si un usuario toca la etiqueta con el texto sin cifrar, la acción de retroceso aún se activa.
dvdblk

1

Estaba luchando con esto porque tenía un controlador de navegación personalizado. Pude eliminar el texto del elemento posterior en todos los controladores de vista con este código en mi clase de controlador de navegación personalizado override func viewDidLayoutSubviews() { self.navigationBar.backItem?.title = "" }

Esto elimina todos los títulos de los elementos posteriores mediante este controlador de navegación personalizado.


1
Actualización para esto: esto funciona pero hay un retraso extraño en la carga que me molesta. Ahora agregué esto 'let BarButtonItemAppearance = UIBarButtonItem.appearance () BarButtonItemAppearance.setTitleTextAttributes ([NSAttributedStringKey.foregroundColor: UIColor.clear], para: .normal)' en el delegado de la aplicación didLaunchWithOptions!
Amy.R

0

En iOS 11, descubrimos que establecer UIBarButtonItemla fuente / color del texto de apariencia en un valor muy pequeño o un color claro hará que desaparezca otro elemento de la barra (el sistema ya no respeta la clase del elemento UIBarButton, lo convertirá en a _UIModernBarButton). Además, configurar el desplazamiento del texto posterior a fuera de la pantalla hará que parpadee durante el pop interactivo.

Así que swizzled addSubView:

+ (void)load {
    if (@available(iOS 11, *)) {
        [NSClassFromString(@"_UIBackButtonContainerView")     jr_swizzleMethod:@selector(addSubview:) withMethod:@selector(MyiOS11BackButtonNoTextTrick_addSubview:) error:nil];
    }
}

- (void)MyiOS11BackButtonNoTextTrick_addSubview:(UIView *)view {
    view.alpha = 0;
    if ([view isKindOfClass:[UIButton class]]) {
        UIButton *button = (id)view;
        [button setTitle:@" " forState:UIControlStateNormal];
    }
    [self MyiOS11BackButtonNoTextTrick_addSubview:view];
}

0
-(void)setNavigationItems{
     UIBarButtonItem *leftBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"**Your title here**" style:UIBarButtonItemStyleBordered target:self action:@selector(backButtonClicked)];   
     self.navigationController.navigationBar.topItem.backBarButtonItem=leftBarButtonItem;
}
-(void)backButtonClicked{
    [self.navigationController popViewControllerAnimated:YES];
}

0

El texto posterior proviene del último controlador de vista navigationItem.title, y navigationItem.titlelo establece automáticamente self.title. Una forma tan fácil de resolver el problema es enganchar setTitle:.navigationItem.title = @""

Pon este código en AppDelegate.mlo hará bien。

    [UIViewController aspect_hookSelector:@selector(setTitle:)
                              withOptions:AspectPositionAfter
                               usingBlock:^(id<AspectInfo> aspectInfo, NSString *title) {
        UIViewController *vc = aspectInfo.instance;
        vc.navigationItem.titleView = ({
            UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
            titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
            titleLabel.text = title;
            titleLabel;
        });
        vc.navigationItem.title = @"";
    } error:NULL];

Más detalles en https://www.jianshu.com/p/071bc50f1475(Simple Chinease)


0

Mi solución: - XCode: 10.2.1 - Swift: 5

  • Controlador de vista principal:
    • self.title = ""
  • Controlador de vista infantil:
    • self.navigationItem.title = "Su título" // para establecer el título del controlador de vista

0

XCode 11.5 Swift 5

Una forma muy simple, aunque quizás un poco engañosa, de hacer esto programáticamente si no necesita el botón de retroceso personalizado es establecer el tamaño de fuente igual a cero en el controlador de vista que está presionando en la pila, llamando a algo como esto desde viewDidLoad

private func setupNavBar() {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithDefaultBackground()
    
    let backButtonAppearance = UIBarButtonItemAppearance()
    backButtonAppearance.normal.titleTextAttributes = [.font: UIFont(name: "Arial", size: 0)!]
    appearance.backButtonAppearance = backButtonAppearance

    navigationItem.standardAppearance = appearance
    navigationItem.scrollEdgeAppearance = appearance
    navigationItem.compactAppearance = appearance
}

-1

Finalmente encontré la solución perfecta para ocultar el texto trasero predeterminado en toda la aplicación.

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

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

-2

El siguiente método funciona en iOS 11 y es seguro que no se bloquee en otras versiones de iOS. Hacer esto puede hacer que su aplicación sea rechazada en la revisión de la App Store, ya que tanto UIModernBarButton como UIBackButtonContainerView son API privadas. Coloque en AppDelegate.

    if
        let UIModernBarButton = NSClassFromString("_UIModernBarButton") as? UIButton.Type,
        let UIBackButtonContainerView = NSClassFromString("_UIBackButtonContainerView") as? UIView.Type {

        let backButton = UIModernBarButton.appearance(whenContainedInInstancesOf: [UIBackButtonContainerView.self])
        backButton.setTitleColor(.clear, for: .normal)
    }

Hacer esto puede hacer que su aplicación sea rechazada en la revisión de la App Store, ya que tanto UIModernBarButton como UIBackButtonContainerView son API privadas.
Groot

Gracias @Groot, agregó su advertencia.
Patrick

-5

Versión Swift, funciona perfectamente a nivel mundial:

 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
    }

7
Debe agregar que esto ocultará todo el texto también rightBarButtons y leftBarButtons, que no regresan.
limfinity

esto no es un solution. Como señaló @limfinity, lo cambiará universalmente para todos los UIBarButtonItem en toda la aplicación
Danut Pralea

Estoy de acuerdo con @limfinity y Danut Pralea, ocultará todo el texto de UIBarButtonItem en toda la aplicación
Pratik Jamariya
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.