Comment ajouter un bouton droit à un UINavigationController?

191

J'essaie d'ajouter un bouton d'actualisation à la barre supérieure d'un contrôleur de navigation sans succès.

Voici l'en-tête:

@interface PropertyViewController : UINavigationController {

}

Voici comment j'essaye de l'ajouter:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain
                                          target:self action:@selector(refreshPropertyList:)];      
        self.navigationItem.rightBarButtonItem = anotherButton;
    }
    return self;
}
Artilheiro
la source

Réponses:

362

Essayez de le faire dans viewDidLoad. En règle générale, vous devriez différer tout ce que vous pouvez jusqu'à ce point de toute façon, quand un UIViewController est lancé, il peut encore s'écouler un certain temps avant qu'il ne s'affiche, inutile de travailler tôt et de bloquer la mémoire.

- (void)viewDidLoad {
  [super viewDidLoad];

  UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(refreshPropertyList:)];          
  self.navigationItem.rightBarButtonItem = anotherButton;
  // exclude the following in ARC projects...
  [anotherButton release];
}

Quant à savoir pourquoi cela ne fonctionne pas actuellement, je ne peux pas dire avec 100% de certitude sans voir plus de code, mais beaucoup de choses se produisent entre l'initialisation et le chargement de la vue, et vous faites peut-être quelque chose qui provoque la réinitialisation de navigationItem dans entre.

Louis Gerbarg
la source
45
Si vous faites cela en dehors de la sous-classe UINavigationController, vous y feriez référence comme ceci: someNavController.topLevelController.navigationItem.rightBarButtonItem = anotherButton
ransomweaver
2
J'étais en train d'implémenter la solution suggérée et mon application a continué à planter jusqu'à ce que je réalise que le nom de la méthode @selector doit se terminer par deux-points (:).
Stealth
10
Même à l'intérieur de la méthode viewDidLoad d'un UINavigationContoller, je devais l'appeler commeself.topViewController.navigationItem.leftBarButtonItem = nextButton;
Joseph
Merci! @Joseph, votre clarification m'a sauvé. (y) :)
Prasanna
38

Essayez d'ajouter le bouton à la navigationItem du contrôleur de vue qui va être poussé sur cette PropertyViewControllerclasse que vous avez créée.

C'est:

MainViewController *vc = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton addTarget:self action:@selector(showInfo) forControlEvents:UIControlEventTouchUpInside];
vc.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:infoButton] autorelease];

PropertyViewController *navController = [[PropertyViewController alloc] initWithRootViewController:vc];

Maintenant, cet infoButton qui a été créé par programme apparaîtra dans la barre de navigation. L'idée est que le contrôleur de navigation récupère ses informations d'affichage (titre, boutons, etc.) à partir de UIViewControllercelui qu'il est sur le point d'afficher. Vous n'ajoutez pas réellement de boutons et autres directement au fichier UINavigationController.

Adam
la source
2
Définir le rightBarButtonItem directement sur UINavigationController n'a pas fonctionné pour moi (comme proposé par Louis Gerbarg ci-dessus). Au lieu de cela, définir l'élément directement sur l'UIViewController à portée de main comme Adem le suggère a fonctionné!
leviathan le
4
+1 pour "Essayez d'ajouter le bouton à la navigationItem du contrôleur de vue qui va être poussé" !
Kjuly
25

Il semble que certaines personnes (comme moi) viennent ici pour savoir comment ajouter un bouton de barre de navigation dans Interface Builder. La réponse ci-dessous montre comment procéder.

Ajouter un contrôleur de navigation à votre storyboard

Sélectionnez votre View Controller, puis dans le menu Xcode, choisissez Editor> Embed In> Navigation Controller .

entrez la description de l'image ici

Vous pouvez également ajouter un à UINavigationBarpartir de la bibliothèque d'objets.

Ajouter un élément de bouton de barre

Faites glisser a UIBarButtonItemde la bibliothèque d'objets vers la barre de navigation supérieure.

entrez la description de l'image ici

Ça devrait ressembler à ça:

entrez la description de l'image ici

Définir les attributs

Vous pouvez double-cliquer sur "Élément" pour changer le texte en quelque chose comme "Actualiser", mais il existe une icône d' actualisation que vous pouvez utiliser. Sélectionnez simplement l'inspecteur d'attributs pour UIBarButtonItemet pour l' élément système, choisissez Actualiser .

entrez la description de l'image ici

Cela vous donnera l'icône d'actualisation par défaut.

entrez la description de l'image ici

Ajouter une action IB

Faites glisser le contrôle de UIBarButtonItemvers le contrôleur de vue pour ajouter un fichier @IBAction.

class ViewController: UIViewController {

    @IBAction func refreshBarButtonItemTap(sender: UIBarButtonItem) {
        
        print("How refreshing!")
    }
    
}

C'est tout.

Suragch
la source
Désolé, je ne peux pas tout à fait comprendre de quoi vous parlez. Essayez de poser une nouvelle question avec une image illustrant de quoi vous parlez. Ajoutez ensuite un lien vers celui-ci ici.
Suragch
@Suragch, comment puis-je faire la même chose avec des fichiers xib au lieu des storyboards? , merci
Cristian Chaparro A.
@CristianChaparroA. Habituellement, les fichiers xib sont pour des vues uniques et la barre de navigation (qui héberge les éléments du bouton de la barre) est pour plusieurs vues. Je n'ai jamais utilisé de xib avec des éléments de bouton de barre. Vous pouvez essayer de poser une nouvelle question, puis créer un lien vers celle-ci ici.
Suragch
14

Il existe un bouton système par défaut pour "Actualiser":

- (void)viewDidLoad {
    [super viewDidLoad];

    UIBarButtonItem *refreshButton = [[[UIBarButtonItem alloc] 
                            initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
                            target:self action:@selector(refreshClicked:)] autorelease];
    self.navigationItem.rightBarButtonItem = refreshButton;

}

- (IBAction)refreshClicked:(id)sender {

}
Manni
la source
11

Vous pouvez utiliser ceci:

Objectif c

UIBarButtonItem *rightSideOptionButton = [[UIBarButtonItem alloc] initWithTitle:@"Right" style:UIBarButtonItemStylePlain target:self action:@selector(rightSideOptionButtonClicked:)];          
self.navigationItem.rightBarButtonItem = rightSideOptionButton;

Rapide

let rightSideOptionButton = UIBarButtonItem()
rightSideOptionButton.title = "Right"
self.navigationItem.rightBarButtonItem = rightSideOptionButton
Vandit Mehta
la source
6
-(void) viewWillAppear:(BOOL)animated
{

    UIButton *btnRight = [UIButton buttonWithType:UIButtonTypeCustom];
    [btnRight setFrame:CGRectMake(0, 0, 30, 44)];
    [btnRight setImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal];
    [btnRight addTarget:self action:@selector(saveData) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barBtnRight = [[UIBarButtonItem alloc] initWithCustomView:btnRight];
    [barBtnRight setTintColor:[UIColor whiteColor]];
    [[[self tabBarController] navigationItem] setRightBarButtonItem:barBtnRight];

}
Gaurav Gilani
la source
Quelqu'un peut-il me dire s'il y a un mal à le faire dans ViewWillAppear au lieu de ViewDidLoad
Niranjan Molkeri
6

Pour Swift 2:

self.title = "Your Title"

var homeButton : UIBarButtonItem = UIBarButtonItem(title: "LeftButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("yourMethod"))

var logButton : UIBarButtonItem = UIBarButtonItem(title: "RigthButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("yourMethod"))

self.navigationItem.leftBarButtonItem = homeButton
self.navigationItem.rightBarButtonItem = logButton
fandro
la source
Je recommanderais d'utiliser le nouveau sélecteur swift2: #selector (classname.functionname)
Emptyless
5

Voici la solution dans Swift (définissez les options selon vos besoins):

var optionButton = UIBarButtonItem()
optionButton.title = "Settings"
//optionButton.action = something (put your action here)
self.navigationItem.rightBarButtonItem = optionButton
vontell
la source
4

Pourquoi êtes-vous des sous-classes UINavigationController - ? Il n'est pas nécessaire de le sous-classer si tout ce que vous avez à faire est d'y ajouter un bouton.

Configurez une hiérarchie avec un UINavigationControlleren haut, puis dans la viewDidLoad:méthode de votre contrôleur de vue racine : configurez le bouton et attachez-le à l'élément de navigation en appelant

[[self navigationItem] setRightBarButtonItem:myBarButtonItem];
Jasarien
la source
1
Voilà une bonne question. Ce que j'essaie de faire est en fait un modèle de conception très courant, qui est un contrôleur d'onglets de base avec un contrôleur de navigation pour chaque onglet. S'il y a une meilleure façon, je suis ouvert aux suggestions. Je devrais peut-être poser cette question aussi.
Artilheiro
4

Tu peux essayer

self.navigationBar.topItem.rightBarButtonItem = anotherButton;
user2999133
la source
A travaillé comme un charme :)
Saurabh Bhatia
3

Swift 4:

override func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "tap me", style: .plain, target: self, action: #selector(onButtonTap))
}

@objc func onButtonTap() {
    print("you tapped me !?")
}
ergunkocak
la source
Utilisez simplement navigationItem.rightBarButtonItem si vous voulez le bouton du côté droit
Ghanshyam Bagul
2
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 110, 50)];
view.backgroundColor = [UIColor clearColor];

UIButton *settingsButton =  [UIButton buttonWithType:UIButtonTypeCustom];
[settingsButton setImage:[UIImage imageNamed:@"settings_icon_png.png"] forState:UIControlStateNormal];
[settingsButton addTarget:self action:@selector(logOutClicked) forControlEvents:UIControlEventTouchUpInside];
[settingsButton setFrame:CGRectMake(40,5,32,32)];
[view addSubview:settingsButton];

UIButton *filterButton =  [UIButton buttonWithType:UIButtonTypeCustom];
[filterButton setImage:[UIImage imageNamed:@"filter.png"] forState:UIControlStateNormal];
[filterButton addTarget:self action:@selector(openActionSheet) forControlEvents:UIControlEventTouchUpInside];
[filterButton setFrame:CGRectMake(80,5,32,32)];
[view addSubview:filterButton];



self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:view];
Sandeep
la source
2

Essayez ceci, cela fonctionne pour moi.

Barre de navigation et image d'arrière-plan également ajoutée au bouton droit.

 UIBarButtonItem *Savebtn=[[UIBarButtonItem alloc]initWithImage:[[UIImage    
 imageNamed:@"bt_save.png"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] 
 style:UIBarButtonItemStylePlain target:self action:@selector(SaveButtonClicked)];
 self.navigationItem.rightBarButtonItem=Savebtn;
Jaywant Khedkar
la source
0
    UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;
Mahesh Aswathanarayana
la source
0
- (void)viewWillAppear:(BOOL)animated
{    
    [self setDetailViewNavigationBar];    
}
-(void)setDetailViewNavigationBar
{
    self.navigationController.navigationBar.tintColor = [UIColor purpleColor];
    [self setNavigationBarRightButton];
    [self setNavigationBarBackButton];    
}
-(void)setNavigationBarBackButton// using custom button 
{
   UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:@"  Back " style:UIBarButtonItemStylePlain target:self action:@selector(onClickLeftButton:)];          
   self.navigationItem.leftBarButtonItem = leftButton;    
}
- (void)onClickLeftButton:(id)sender 
{
   NSLog(@"onClickLeftButton");        
}
-(void)setNavigationBarRightButton
{

  UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(onClickrighttButton:)];          
self.navigationItem.rightBarButtonItem = anotherButton;   

}
- (void)onClickrighttButton:(id)sender 
{
   NSLog(@"onClickrighttButton");  
}
tv.ashvin
la source
0
    self.navigationItem.rightBarButtonItem =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshData)];



}

-(void)refreshData{
    progressHud= [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
    [progressHud setLabelText:@"拼命加载中..."];
    [self loadNetwork];
}
Gank
la source
0

Vous devez ajouter votre barButtonItem dans - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animatedmethod.

Retik
la source
0

Copiez et collez simplement ce code Objective-C.

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self addRightBarButtonItem];
}
- (void) addRightBarButtonItem {
    UIButton *btnAddContact = [UIButton buttonWithType:UIButtonTypeContactAdd];
    [btnAddContact addTarget:self action:@selector(addCustomerPressed:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:btnAddContact];
    self.navigationItem.rightBarButtonItem = barButton;
}

#pragma mark - UIButton
- (IBAction)addCustomerPressed:(id)sender {
// Your right button pressed event
}
Vivek
la source
J'essaye d'aider
Vivek
0

Ce problème peut se produire si nous supprimons le contrôleur de vue ou essayons d'ajouter un nouveau contrôleur de vue dans le générateur d'interface (main.storyboard). Pour résoudre ce problème, il faut ajouter «Élément de navigation» dans le nouveau contrôleur de vue. Parfois, il arrive que nous créons un nouvel écran de contrôleur de vue et qu'il ne se connecte pas automatiquement à "Élément de navigation".

  1. Accédez au tableau principal.
  2. Sélectionnez ce nouveau contrôleur de vue.
  3. Accédez au plan du document.
  4. Vérifiez la vue du contenu du contrôleur.
  5. Si le nouveau contrôleur de vue n'a pas d'élément de navigation, copiez l'élément de navigation du contrôleur de vue précédent et collez-le dans le nouveau contrôleur de vue.
  6. enregistrez et nettoyez le projet.
NilamK
la source
0

Vous pouvez également ajouter plusieurs boutons en utilisant rightBarButtonItems

-(void)viewDidLoad{

    UIBarButtonItem *button1 = [[UIBarButtonItem alloc] initWithTitle:@"button 1" style:UIBarButtonItemStylePlain target:self action:@selector(YOUR_METHOD1:)];
    UIBarButtonItem *button2 = [[UIBarButtonItem alloc] initWithTitle:@"button 2" style:UIBarButtonItemStylePlain target:self action:@selector(YOUR_METHOD2:)];

    self.navigationItem.rightBarButtonItems = @[button1, button2];
}
yoAlex5
la source
-1

@Artilheiro: Si c'est un projet basé sur la navigation, vous pouvez créer BaseViewController. Toutes les autres vues hériteront de cette BaseView. Dans BaseView, vous pouvez définir des méthodes génériques pour ajouter le bouton droit ou pour modifier le texte du bouton gauche.

ex:

@interface BaseController: UIViewController {

} - (void) setBackButtonCaption: (NSString *) légende;

(void) setRightButtonCaption: (NSString *) caption selectot: sélecteur (SEL);

@end // Dans BaseView.M

(void) setBackButtonCaption: (NSString *) caption {

UIBarButtonItem *backButton =[[UIBarButtonItem alloc] init];

backButton.title= caption;
self.navigationItem.backBarButtonItem = backButton;
[backButton release];

} - (void) setRightButtonCaption: (NSString *) caption selectot: (SEL) selector {

  UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] init];
rightButton.title = caption;

rightButton.target= self;

[rightButton setAction:selector];

self.navigationItem.rightBarButtonItem= rightButton;

[rightButton release];

}

Et maintenant, dans n'importe quelle vue personnalisée, implémentez cette vue de base appelez les méthodes:

@interface LoginView: BaseController {

Dans certaines méthodes, appelez la méthode de base comme suit:

SEL sel = @selector (switchToForgotPIN);

[super setRightButtonCaption: @ "PIN oublié" selectot: sel];

iPhoneDev
la source