35 votes

Comment créer backBarButtomItem avec une vue personnalisée pour un UINavigationController

J'ai un UINavigationController dans lequel je pousse plusieurs points de vue. À l'intérieur de viewDidLoad pour l'une de ces vues, je souhaite définir le self.navigationItem.backBarButtonItem sur une vue personnalisée (basée sur une image personnalisée). Je ne sais pas pourquoi, mais cela ne semble pas fonctionner. Au lieu de cela, je reçois le bouton "retour" standard.

 UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 63, 30)];
[backButton setImage:[UIImage imageNamed:@"back_OFF.png"] forState:UIControlStateNormal];
[backButton setImage:[UIImage imageNamed:@"back_ON.png"] forState:UIControlStateSelected];
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.backBarButtonItem = backButtonItem;
[backButtonItem release];
[backButton release];
 

J'ai testé avec un titre standard et cela a fonctionné. Quel est le problème avec le code ci-dessus?

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

Merci pour toute aide à ce sujet.

27voto

Michael G. Emmons Points 16681

Comme de iOS5, nous avons une excellente nouvelle façon de personnaliser l'apparence de presque n'importe quel contrôle à l'aide de la UIAppearance protocole, c'est à dire [UIBarButtonItem appearance]. L'apparition de proxy vous permet de créer de l'application des modifications à l'échelle de l'aspect des contrôles. Ci-dessous est un exemple d'un bouton de retour créé avec l'apparition de proxy.

enter image description here

Utiliser l'exemple de code ci-dessous pour créer un bouton de retour avec des images personnalisées pour normal et mis en évidence les états. Appeler la méthode suivante de vous appDelegate de l' application:didFinishLaunchingWithOptions:

- (void) customizeAppearance {

UIImage *i1 = [[UIImage imageNamed:@"custom_backButton_30px"]
                      resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 6)];
UIImage *i2 = [[UIImage imageNamed:@"custom_backButton_24px"] 
                      resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 6)];

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:i1 
                              forState:UIControlStateNormal 
                              barMetrics:UIBarMetricsDefault];

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:i2 
                              forState:UIControlStateNormal 
                              barMetrics:UIBarMetricsLandscapePhone];

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:i1
                              forState:UIControlStateHighlighted 
                              barMetrics:UIBarMetricsDefault];

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:i2 
                              forState:UIControlStateHighlighted 
                              barMetrics:UIBarMetricsLandscapePhone];
}

C'est juste un exemple rapide. Normalement, vous voulez avoir des images séparées pour le mode normal et mis en évidence (pressé) de l'état.

Si vous êtes intéressé dans la personnalisation de l'apparence des autres contrôles, quelques bons exemples peuvent être trouvés ici: http://ios.biomsoft.com/2011/10/13/user-interface-customization-in-ios-5/

19voto

Travis Points 517

Je suis à peu près certain que backBarButtonItem est une propriété en lecture seule. Au lieu de modifier les backBarButtonItem , essayez de définir une personnalisation leftBarButtonItem et masquez le backBarButtonItem :

 self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Prout" style:UIBarButtonItemStyleDone target:nil action:nil] autorelease];
self.navigationItem.hidesBackButton = YES;
 

Vous devrez également vous assurer de brancher le bouton personnalisé pour rappeler l'action sur le UINavigationBar .

15voto

Vivi Points 505

Je n'ai jamais été en mesure de créer un UIBarButtonItem approprié avec une vue personnalisée et setBackBarButtonItem .

Voici la solution que j'ai trouvée: laissez net UINavigationControllerDelegate s'occuper de tout! Le truc ici consiste à appeler la méthode popViewControllerAnimated: des viewController.navigationController afin de ne pas avoir à créer de méthode personnalisée.

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if([navigationController.viewControllers count ] > 1) {
        UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0,0,70,35)];
        UIButton *myBackButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
        [myBackButton setFrame:CGRectMake(0,0,70,35)];
        [myBackButton setImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
        [myBackButton setEnabled:YES];
        [myBackButton addTarget:viewController.navigationController action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
        [backButtonView addSubview:myBackButton];
        [myBackButton release];
        UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
        viewController.navigationItem.leftBarButtonItem = backButton;
        [backButtonView release];
        [backButton release];
    }
}
 

10voto

Paul Points 101

Si votre objectif final est de simplement remplacer l'image utilisée pour le bouton de retour, vous pouvez utiliser une nouvelle méthode de UIBarButtonItem disponible dans la version 5.0 d'iOS:

setBackButtonBackgroundImage:forState:barMetrics:

Apple Docs: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIBarButtonItem_Class/Reference/Reference.html

Voici un exemple simple qui définit une image de fond personnalisée pour tous les boutons de retour dans votre application:

UIImage *toolbarBackButtonBackgroundPortrait = [[UIImage imageNamed:@"toolbarBackButtonPortrait"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 17, 0, 6)];
UIImage *toolbarBackButtonBackgroundLandscape = [[UIImage imageNamed:@"toolbarBackButtonLandscape"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 17, 0, 6)];

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:toolbarBackButtonBackgroundPortrait forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:toolbarBackButtonBackgroundLandscape forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];

6voto

LucasTizma Points 5452

Je serais prêt à parier que c'est un bug de la part d'Apple que je suis en cours d'exécution dans le exact même problème. La raison en est que je peux obtenir une mesure UIBarButtonItem à apparaître, mais seulement quand je ne pas essayer d'utiliser l' initWithCustomView: méthode. Par l'API, la manette de navigation vérifie les éléments suivants, lorsqu'un nouveau-vue-contrôleur est poussé:

  1. Si le nouveau haut-niveau-vue-contrôleur a une coutume gauche bouton de la barre d'élément, cet élément est affiché. Pour préciser la personnalisation d'un gauche bouton de la barre d'élément, de définir les leftBarButtonItem propriété de l'avis du contrôleur d'élément de navigation.
  2. Si l'affichage de niveau supérieur contrôleur ne dispose pas d'une coutume gauche bouton de la barre d'élément, mais l'élément de navigation de l'affichage précédent contrôleur a un élément valide dans son backBarButtonItem propriété, la barre de navigation affiche l'élément en question.
  3. Si une coutume bouton de la barre d'élément n'est pas spécifié par le point de vue des contrôleurs, un défaut de bouton de retour est utilisé et son titre est définie à la valeur de la propriété de titre de la vue précédente contrôleur-qui est, le point de vue du contrôleur descend d'un niveau dans la pile. (Si il y a une seule vue-contrôleur sur la pile de navigation, pas de bouton de retour est affiché.)

Mon cas (comme le vôtre) est de 2. Je spécifier un code exactement la même que la vôtre (c'est à dire, la création d'un UIButton, en définissant son image propriétés pour les différents états, la création d'un UIBarButtonItem, l'initialiser avec l' UIButton, alors la configuration de ma vue actuelle du contrôleur backBarButtonItem de la propriété de l' UIBarButtonItem); toutefois, quand plus tard, j'ai pousser mon point de vue, contrôleur, rien ne s'affiche sur le côté gauche de ma manette de navigation. Étrangement, j'pouvez cliquer sur le bouton "Retour" doit être, et il apparaît de la vue-contrôleur.

Fait intéressant, si je crée un UIBarButtonItem à l'aide de l' initWithTitle:style:target:action: méthode au lieu de l' initWithCustomView: méthode, il n' afficher un bouton personnalisé avec un titre personnalisé. Aussi, comme Travis mentionné, à l'aide de l' leftBarButtonItem de la propriété au lieu de cela fonctionne très bien. Je préfère adhérer à l'sanctionné logique, cependant, en spécifiant le bouton "Retour" pour le point de vue actuel contrôleur -- être affichée plus tard, quand un nouveau-vue-contrôleur est poussé -- au lieu de créer un gauche bouton de la fenêtre contrôleur, qui, sans doute, ne devrait avoir aucun souci pour quoi que ce soit se rapportant à la vue-contrôleur qui est venu avant lui. :-\

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X