web-dev-qa-db-fra.com

Suppression du texte du titre d'un UIBarButtonItem iOS

Ce que je voulais faire, c'est supprimer le texte du bouton "Retour" d'une UIBarButtonItem, en ne laissant que le chevron bleu sur la barre de navigation. N'oubliez pas que je développe pour iOS 7. J'ai essayé plusieurs méthodes, notamment:

Voici la méthode d'image que je n'ai pas aimée (l'image semblait déplacée):

UIBarButtonItem *barBtnItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"iOS7BackButton"] style:UIBarButtonItemStylePlain target:self action:@selector(goToPrevious:)];
self.navigationItem.leftBarButtonItem = barBtnItem;

Une autre méthode que j'ai essayée était la suivante: elle ne fonctionnait tout simplement pas (rien n'était affiché):

UIBarButtonItem *barBtn = [[UIBarButtonItem alloc]init];
barBtn.title=@"";
self.navigationItem.leftBarButtonItem=barBtn;

Ce que je voulais réaliser, c’est un peu comme les boutons du dos de l’application iOS 7 Music, qui ne comportait qu’un seul chevron. 

Merci.

194
Pan Ziyue
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60, -60)
                                                         forBarMetrics:UIBarMetricsDefault];

Ensuite, vous pouvez supprimer le titre de l'élément du bouton Retour. 

Si vous utilisez Storyboard, vous pouvez définir l'inspecteur des attributs de navigation avec le bouton Précédent avec un espace. 

200
andyleehao

Pour définir le titre du bouton de retour d'un contrôleur de vue sans changer de titre, utilisez:

Objectif c:

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

Rapide:

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

Pour être clair, cela se fait sur le contrôleur de vue que vous verriez si vous appuyez sur le bouton Retour. i.e. Au lieu de voir "<Paramètres", vous voulez simplement voir "<", puis sur votre SettingsViewController, vous mettriez ceci dans votre init. Dans ce cas, vous ne rencontrerez aucun des problèmes liés au fait que le titre ne s'affiche pas lorsque vous regardez le contrôleur de vue lui-même. 

406
DonnaLea

Si vous utilisez Storyboards, vous pouvez accéder à Attributes Inspector du Navigation Item du ViewController (cliquer sur Navigation Bar) et définir la propriété Back Button sur "" (un caractère d'espacement). Cela définira le titre du bouton Précédent sur un caractère d'espacement, laissant le chevron visible. Pas besoin de jouer avec le code.

example image

Notez que ceci va définir Back Button title pour le bouton Précédent qui se liera à ce contrôleur de vue à celui qui a été poussé dessus, pas pour le Back Button qui sera affiché dans ce contrôleur!

126
Nikita Kukushkin

Cela me permet d'afficher uniquement le chevron «arrière» sans texte:

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

Définissez cette propriété dans viewDidLoad du contrôleur de vue présentant la barre de navigation et tout ira bien.

Remarque: je ne l'ai testé que sur iOS 7, ce qui correspond à la portée de la question.

122
Guto Araujo

Lorsque vous définissez le titre du bouton, utilisez @ "" au lieu de @ "".

--MODIFIER--

Est-ce que quelque chose change lorsque vous essayez d'autres chaînes? J'utilise moi-même le code suivant avec succès:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:backString style:UIBarButtonItemStyleDone target:nil action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];

backString est une variable définie sur @ "" ou @ "Back", selon que je suis sur iOS 7 ou une version antérieure.

Une chose à noter est que ce code n'est pas dans le contrôleur pour la page pour laquelle je veux personnaliser le bouton Précédent. C'est en fait dans le contrôleur avant sur la pile de navigation.

27
Kamaros

 enter image description here

Parfois, il est utile de voir les choses dans leur contexte. Voici un projet minimal qui cache le texte "retour" mais montre toujours la flèche.

Storyboard

 enter image description here

Il existe une séquence entre le bouton "Afficher le second contrôleur de vue" et le second contrôleur de vue. 

J'ai également ajouté un élément de navigation au deuxième contrôleur de vue afin qu'il ait un titre. C'est facultatif. Cela n'affecte pas le bouton retour.

Code

FirstViewController.Swift

import UIKit
class FirstViewController: UIViewController {

    @IBAction func showSecondViewControllerButtonTapped(sender: UIButton) {

        // hide the back button text
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
}

(SecondViewController.Swift} _

import UIKit
class SecondViewController: UIViewController {
    // Nothing at all needed here
}

Méthode alternative (IB uniquement, pas de code)

Dans le storyboard, sélectionnez l'élément de navigation pour le contrôleur de vue premier (pas le second). Entrez simplement un espace pour le texte du bouton Précédent.

 enter image description here

26
Suragch
self.navigationController.navigationBar.topItem.title = @"";
15
Claudio Castro

Sur iOS7, Apple a introduit deux nouvelles propriétés dans UINavigationBar, 'backIndicatorTransitionMaskImage' et 'backIndicatorImage'.

En appelant simplement une fois:

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"your_image"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"your_image_mask"]];

Il rendra une image personnalisée à la place du glyphe en chevron par défaut, en héritant de la couleur de teinte de keyWindow.

Et pour supprimer le titre, je vais suggérer la réponse de Kamaros. N'oubliez pas d'appeler ce code sur le contrôleur de vue qui pousse votre nouveau contrôleur de vue. Suppression du texte du titre d'un UIBarButtonItem iOS

11
DZenBot

Cela a fonctionné pour moi dans iOS10. Appelez cela depuis viewDidLoad du contrôleur de vue.

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

Je n’ai pas eu beaucoup de succès avec les réponses fournies mais j’ai trouvé un moyen très simple de contourner le problème. Dans votre storyboard, vous pouvez cliquer sur l'élément de navigation de votre UIViewController et définir le texte du bouton Précédent. Je l'ai mis sur un seul espace et cela m'a donné le comportement que je cherchais.enter image description here

10
Grahambo

La solution simple à ce problème, fonctionnant sur iOS7 ainsi que sur 6, consiste à définir une vue de titre personnalisée dans viewDidLoad:

- (void)viewDidLoad {

    [super viewDidLoad];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    titleLabel.text = self.title;
    titleLabel.backgroundColor = [UIColor clearColor];

    [titleLabel sizeToFit];

    self.navigationItem.titleView = titleLabel;
}

Ensuite, dans viewWillAppear: vous pouvez appeler en toute sécurité

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

Comme votre vue de titre est une vue personnalisée, elle ne sera pas écrasée lors du retour dans la pile de navigation.

6
Matthes

En fait, vous pouvez le faire avec un seul truc: 

Remplacez la classe UINavigationBar et ajoutez cette ligne de code:

- (void)layoutSubviews{
    self.backItem.title = @"";
    [super layoutSubviews];
}

Puis initialisez votre UINavigationController avec cette classe UINavigationBar personnalisée, etc. etc. UINavigationController * navController = [[UINavigationController alloc] initWithNavigationBarClass:[CBCNavigationBar class] toolbarClass:nil];

J'espère que cela t'aides

6
rordulu

Dans la méthode prepareForSegue: de votre premier ViewController, vous définissez le titre de cette vue sur @ "". Ainsi, lorsque la vue suivante est insérée, le titre précédent de ViewController sera affiché: @ "".

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    self.navigationItem.title = @" ";
}

Le seul problème avec cela est que, lorsque vous appuyez sur le bouton Précédent, votre vue précédente n'a pas de titre. Vous pouvez donc l'ajouter à nouveau à viewWillAppear:

- (void)viewWillAppear:(BOOL)animated{
    self.navigationItem.title = @"First View Title";
}

Je n'aime pas beaucoup cette solution mais cela fonctionne et je n'ai pas trouvé d'autre moyen de le faire.

5
Alejandro Figueroa

J'ai été capable de bricoler quelque chose ensemble en utilisant la réponse de DonnaLea. Voici comment la solution apparaît dans ma sous-classe UIViewController:

var backItemTitle:String?

override func viewDidLoad() {
    super.viewDidLoad()

    //store the original title
    backItemTitle = self.navigationController?.navigationBar.topItem?.title

    //remove the title for the back button
    navigationController?.navigationBar.topItem?.title = ""
}

override func willMoveToParentViewController(parent: UIViewController?) {
    super.willMoveToParentViewController(parent)
    if parent == nil {

        //restore the orignal title
        navigationController?.navigationBar.backItem?.title = backItemTitle
    }
}

Le problème avec la réponse d'origine est qu'elle supprime le titre du contrôleur lorsque vous y revenez. Tenter de réinitialiser le titre dans viewWillDisappear est trop tard dans le processus de transition; Cela provoque le retour du titre au lieu d’une belle animation. Cependant, willMoveToParentViewController arrive plus tôt et permet le comportement correct.

Mise en garde: je l'ai seulement testé avec un Push/Pop UINavigationController normal. Il peut y avoir un comportement inattendu supplémentaire dans d'autres situations.

4
BradB

Aucune des réponses ne m'a aidé. Mais une astuce a fait - je viens d'effacer le titre du contrôleur de vue qui a poussé (où le bouton de retour va se placer) juste avant de le pousser.

Ainsi, lorsque la vue précédente n'a pas de titre, sur iOS 7, le bouton Précédent ne comporte qu'une flèche, sans texte.

Sur viewWillAppear de la vue de diffusion, j'ai replacé le titre d'origine.

3
Kof

L’utilisation de la sous-classe navigationController supprime le "Retour".

J'utilise ceci pour le supprimer, de manière permanente via l'application.

//.h
@interface OPCustomNavigationController : UINavigationController 

@end

//.m
@implementation OPCustomNavigationController

- (void)awakeFromNib
{
    [self backButtonUIOverride:YES];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self backButtonUIOverride:NO];

    [super pushViewController:viewController animated:animated];
}

- (void)backButtonUIOverride:(BOOL)isRoot
{
    if (!self.viewControllers.count)
        return;

    UIViewController *viewController;

    if (isRoot)
    {
        viewController = self.viewControllers.firstObject;
    }
    else
    {
        int previousIndex = self.viewControllers.count - 1;

        viewController = [self.viewControllers objectAtIndex:previousIndex];
    }

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

@end
3
0yeoj

Swift 3

navigationController?.navigationBar.topItem?.title = ""
3
Jiří Zahálka
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefaultPrompt];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(10.0, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],
                                                               NSFontAttributeName:[UIFont systemFontOfSize:1]}
                                                    forState:UIControlStateNormal];
3
Bill Xie
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];

    [[UIBarButtonItem appearance] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];

J'avais un même problème et je l'ai fait de cette façon. 

--MODIFIER--

c'est une solution lorsque vous voulez vraiment supprimer le titre de tout UIBarbuttonItem. Si vous souhaitez uniquement supprimer le titre du bouton de la barre arrière, il n’existe pas de solution simple et pratique. Dans mon cas, comme je n'ai que quelques UIBarButtonItems qui ont besoin d'afficher le texte du titre, je viens de changer le titre de ces boutons spécifiques. Si vous voulez être plus spécifique, utilisez le code ci-dessous, qui ne changera que les boutons de la barre de navigation:

NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];
3
andylee

Masquer le bouton Précédent Titre de la barre de navigation

UIBarButtonItem *barButton = [[UIBarButtonItem alloc] init];
barButton.title = @""; // blank or any other title
self.navigationController.navigationBar.topItem.backBarButtonItem = barButton;
2
Kirit Vaghela

Voici ce que je fais moi, ce qui est plus simple pour supprimer le titre du bouton de retour

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar?.backItem?.title = ""
}
2
YannickSteph

C'est une meilleure solution.

Une autre solution est dangereuse parce que c'est du hack.

extension UINavigationController {

    func pushViewControllerWithoutBackButtonTitle(_ viewController: UIViewController, animated: Bool = true) {
        viewControllers.last?.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        pushViewController(viewController, animated: animated)
    }
}
1
taku_oka

Vous pouvez aussi utiliser ceci:

UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init];
temporaryBarButtonItem.title = @"";
self.navigationItem.backBarButtonItem = temporaryBarButtonItem;

[temporaryBarButtonItem release];

Ça marche pour moi

1
Utkarsh 786

Je crée une classe personnalisée pour UINavigationController et l'applique à tous les contrôleurs de navigation de mon application. Dans cette classe UINavigationController personnalisée, je règle le délégué UINavigationBar sur self une fois la vue chargée.

- (void)viewDidLoad {
    self.navigationBar.delegate = self;
}

Ensuite, j'implémente la méthode delegate:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item {

    // This will clear the title of the previous view controller
    // so the back button is always just a back chevron without a title
    if (self.viewControllers.count > 1) {
        UIViewController *previousViewController = [self.viewControllers objectAtIndex:(self.viewControllers.count - 2)];
        previousViewController.title = @"";
    }
    return YES;
}

De cette façon, j'attribue simplement ma classe personnalisée à tous mes contrôleurs de navigation, ce qui efface le titre de tous les boutons de retour. Et pour plus de clarté, j’ai toujours défini le titre de tous mes autres contrôleurs de vue dans viewWillAppear de manière à ce que le titre soit toujours mis à jour juste avant que la vue n’apparaisse (au cas où elle serait supprimée par de tels trucs).

1
nurider

Si, comme moi, vous utilisez un affichage personnalisé au lieu de la variable UINavigationBar et que vous êtes bloqué avec le bouton Précédent, vous devez effectuer un travail un peu moins précis. 

[self.navigationController.navigationBar setHidden:NO];
self.navigationController.navigationBar.topItem.title = @"";
[self.navigationController.navigationBar setHidden:YES];

Il semble que si le titre n’est pas présenté, peu importe ce que l’on essaie de montrer, le titre est affiché puis caché avant qu’il soit tracé et que le problème soit résolu.

1
Nicholas Smith
extension UIViewController{
    func hideBackButton(){
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
}
1
Maor

Swift 3.1 Vous pouvez le faire en implémentant la méthode déléguée de UINavigationController. Cela cachera le titre avec le bouton précédent seulement, nous aurons toujours l'image de la flèche arrière et les fonctionnalités par défaut.

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

Solution parfaite à l'échelle mondiale

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
}
1
PeiweiChen
case : <Back as <

override func viewWillAppear(animated: Bool) {
navigationController!.navigationBar.topItem!.title = ""
    }
1
A.G

J'ai fait une catégorie très simple de zéro configuration pour masquer tous les titres de bouton de retour via l'application, vous pouvez le vérifier ici . Cette question a déjà accepté la réponse, mais pour d'autres cela peut être utile.

MODIFIER:

fichier .h

#import <UIKit/UIKit.h>

@interface UINavigationController (HideBackTitle)
extern void PJSwizzleMethod(Class cls, SEL originalSelector, SEL swizzledSelector);

@end

fichier .m

#import "UINavigationController+HideBackTitle.h"
#import <objc/runtime.h>


@implementation UINavigationController (HideBackTitle)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        PJSwizzleMethod([self class],
                    @selector(pushViewController:animated:),
                    @selector(pj_pushViewController:animated:));
    });
}

- (void)pj_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    UIViewController *disappearingViewController =  self.viewControllers.lastObject;
    if (disappearingViewController) {
        disappearingViewController.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    }
    if (!disappearingViewController) {
        return [self pj_pushViewController:viewController animated:animated];
    }
    return [self pj_pushViewController:viewController animated:animated];
}



@end

void PJSwizzleMethod(Class cls, SEL originalSelector, SEL swizzledSelector)
{
    Method originalMethod = class_getInstanceMethod(cls, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);

    BOOL didAddMethod =
    class_addMethod(cls,
                originalSelector,
                method_getImplementation(swizzledMethod),
                method_getTypeEncoding(swizzledMethod));

    if (didAddMethod) {
        class_replaceMethod(cls,
                        swizzledSelector,
                        method_getImplementation(originalMethod),
                        method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}
0
Pratik Jamariya

Je ne pouvais pas le faire fonctionner en utilisant la réponse de Guto Araujo de navigationBar.topItem.title = @"";

Cependant, j'ai pu obtenir l'effet souhaité en définissant self.title = @"" dans la méthode init de mon contrôleur de vue. (Le réglage dans init est important, viewDidLoad ne fonctionnera pas.)

0
zekel

Je liste les solutions qui ont fonctionné pour moi jusqu'à présent.

override func viewDidLoad() {
super.viewDidLoad()   



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

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

UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Normal) //3

UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Highlighted) //4   



}
0
A.G

Il suffit d'entrer un seul espace pour l'élément de navigation du bouton Précédent!

0
VirajP

Si vous souhaitez supprimer le titre de l'élément de bouton de retour dans iOS11, vous pouvez l'essayer! 

@implementation UIView (PrivateBackButton)

    + (void)initialize {
        if ([NSProcessInfo processInfo].operatingSystemVersion.majorVersion < 11.0) return;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [NSObject hookInstanceMethodForClass:[self class] originalMethod:@selector(layoutSubviews) newMethod:@selector(mc_layoutSubviews)];
        });
    }

    - (void)mc_layoutSubviews {
        [self mc_layoutSubviews];
        [self updateiOS11LaterUI];
    }

    - (void)updateiOS11LaterUI {
        if ([NSProcessInfo processInfo].operatingSystemVersion.majorVersion < 11.0) return;
        if (![self isKindOfClass:NSClassFromString(@"_UIBackButtonContainerView")]) return;

        [self removeAllSubviews];
        [self.superview mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.width.mas_equalTo(@44);
        }];
    }

    @end
0
l1Dan

Dans iOS 11, vous pouvez utiliser le code suivant pour masquer le titre du bouton précédent:

Rapide:

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

Ce code ne supprime pas le titre de la barre de navigation, mais le rend simplement transparent. Le bouton Précédent conserve toujours un espace pour le titre. Si vous avez besoin de plus d'espace pour le titre du contrôleur de vue, vous devez utiliser une autre solution.

0
Serhiy

Implémentez votre propre classe de base UIViewController et substituez setTitle:.

@interface CustomViewController : UIViewController
@end

@implementation CustomViewController

- (void)setTitle:(NSString *)title {
    super.title = @""; // This will remove the "Back" title
    UILabel *titleView = [UILabel new];
    // customize the label as you wish
    titleView.text = title;
    [titleView sizeToFit];
    self.navigationItem.titleView = titleView;
}

@end

Désormais, dans toute UIViewController où vous souhaitez définir le titre, vous pouvez simplement écrire self.title = @"MyTitle" comme vous le feriez normalement, et aucun texte n'apparaîtra dans l'élément de barre arrière lors du transfert d'une nouvelle UIViewController.

0
Avi