Wie füge ich einem UINavigationController eine rechte Schaltfläche hinzu?


191

Ich versuche, eine Aktualisierungsschaltfläche zur oberen Leiste eines Navigationscontrollers hinzuzufügen, ohne Erfolg.

Hier ist der Header:

@interface PropertyViewController : UINavigationController {

}

Hier ist, wie ich versuche, es hinzuzufügen:

- (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;
}

Antworten:


362

Versuchen Sie es in viewDidLoad. Im Allgemeinen sollten Sie alles, was Sie können, bis zu diesem Zeitpunkt aufschieben. Wenn ein UIViewController gestartet wird, kann es noch eine Weile dauern, bis er angezeigt wird. Es macht keinen Sinn, frühzeitig zu arbeiten und Speicher zu binden.

- (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];
}

Warum es derzeit nicht funktioniert, kann ich nicht mit 100% iger Sicherheit sagen, ohne mehr Code zu sehen, aber zwischen init und dem Laden der Ansicht passiert viel, und Sie tun möglicherweise etwas, das dazu führt, dass das Navigationselement zurückgesetzt wird zwischen.


45
Wenn Sie dies außerhalb der UINavigationController-Unterklasse tun, verweisen Sie wie folgt darauf: someNavController.topLevelController.navigationItem.rightBarButtonItem = anotherButton
ransomweaver

2
Ich habe die vorgeschlagene Lösung implementiert und meine App stürzte immer wieder ab, bis mir klar wurde, dass der Name der @ selector-Methode mit einem Doppelpunkt (:) enden muss.
Stealth

10
Selbst innerhalb der viewDidLoad-Methode eines UINavigationContoller musste ich es so nennenself.topViewController.navigationItem.leftBarButtonItem = nextButton;
Joseph

Vielen Dank! @ Joseph, Ihre Klarstellung hat mich gerettet. (y) :)
Prasanna

38

Fügen Sie die Schaltfläche zum Navigationselement des Ansichtscontrollers hinzu, das darauf verschoben werden soll PropertyViewController Ihnen erstellte Klasse verschoben werden soll.

Das ist:

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];

Dieser programmgesteuert erstellte infoButton wird nun in der Navigationsleiste angezeigt. Die Idee ist, dass der Navigationscontroller seine Anzeigeinformationen (Titel, Schaltflächen usw.) von der Anzeige abruft, die UIViewControllerer anzeigen möchte. Sie fügen tatsächlich keine Schaltflächen und dergleichen direkt zum hinzu UINavigationController.


2
Das Einstellen des rightBarButtonItem direkt auf dem UINavigationController hat bei mir nicht funktioniert (wie oben von Louis Gerbarg vorgeschlagen). Stellen Sie das Element stattdessen direkt auf dem UIViewController ein, wie Adem es vorgeschlagen hat!
Leviathan

4
+1 für "Versuchen Sie, die Schaltfläche zum Navigationselement des Ansichts-Controllers hinzuzufügen, der gedrückt werden soll" !
7.

25

Es scheint, dass einige Leute (wie ich) hierher kommen und nach Möglichkeiten suchen, eine Navigationsleistenschaltfläche im Interface Builder hinzuzufügen. Die Antwort unten zeigt, wie es geht.

Fügen Sie Ihrem Storyboard einen Navigations-Controller hinzu

Wählen Sie Ihren View Controller aus und wählen Sie dann im Xcode-Menü Editor> Einbetten> Navigations-Controller .

Geben Sie hier die Bildbeschreibung ein

Alternativ können Sie eine UINavigationBaraus der Objektbibliothek hinzufügen .

Fügen Sie ein Balkenschaltflächenelement hinzu

Ziehen Sie a UIBarButtonItemaus der Objektbibliothek in die obere Navigationsleiste.

Geben Sie hier die Bildbeschreibung ein

Es sollte so aussehen:

Geben Sie hier die Bildbeschreibung ein

Legen Sie die Attribute fest

Sie könnten einen Doppelklick auf „Item“ , um den Text zu so etwas wie „Refresh“ zu ändern, aber es ist eine tatsächliche Symbol für Refresh , dass Sie verwenden können. Wählen Sie einfach den Attributinspektor für das UIBarButtonItemund für Systemelement die Option Aktualisieren .

Geben Sie hier die Bildbeschreibung ein

Dadurch erhalten Sie das Standard-Aktualisierungssymbol.

Geben Sie hier die Bildbeschreibung ein

Fügen Sie eine IB-Aktion hinzu

Ziehen Sie UIBarButtonItemmit gedrückter Ctrl-Taste zum View Controller, um eine hinzuzufügen @IBAction.

class ViewController: UIViewController {

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

Das ist es.


Entschuldigung, ich kann nicht ganz verfolgen, wovon Sie sprechen. Stellen Sie eine neue Frage mit einem Bild, das zeigt, wovon Sie sprechen. Dann fügen Sie hier einen Link hinzu.
Suragch

@Suragch, wie kann ich die gleichen Dinge mit xib-Dateien anstelle von Storyboards machen? , danke
Cristian Chaparro A.

@CristianChaparroA. Normalerweise sind XIB-Dateien für einzelne Ansichten und die Navigationsleiste (in der sich die Elemente der Leistenschaltfläche befinden) für mehrere Ansichten. Ich habe noch nie ein xib mit Balkenknopfelementen verwendet. Sie können versuchen, eine neue Frage zu stellen und dann hier darauf verlinken.
Suragch

14

Es gibt eine Standardsystemschaltfläche für "Aktualisieren":

- (void)viewDidLoad {
    [super viewDidLoad];

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

}

- (IBAction)refreshClicked:(id)sender {

}

11

Sie können dies verwenden:

Ziel c

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

Schnell

let rightSideOptionButton = UIBarButtonItem()
rightSideOptionButton.title = "Right"
self.navigationItem.rightBarButtonItem = rightSideOptionButton

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];

}

Kann mir jemand sagen, dass es Schaden anrichtet, dies in ViewWillAppear anstelle von ViewDidLoad
Niranjan Molkeri

6

Für schnelle 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

Ich würde empfehlen, den neuen swift2-Selektor zu verwenden: #selector (classname.functionname)
Emptyless

5

Hier ist die Lösung in Swift (Optionen nach Bedarf einstellen):

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

4

Warum bist du Unterklassen? UINavigationController ? Es ist nicht erforderlich, eine Unterklasse zu erstellen, wenn Sie lediglich eine Schaltfläche hinzufügen müssen.

Richten Sie eine Hierarchie mit einem UINavigationControlleroben und dann in der viewDidLoad:Methode Ihres Root-View-Controllers ein : Richten Sie die Schaltfläche ein und hängen Sie sie durch Aufrufen an das Navigationselement an

[[self navigationItem] setRightBarButtonItem:myBarButtonItem];

1
Das ist eine gute Frage. Was ich versuche zu tun, ist eigentlich ein sehr verbreitetes Entwurfsmuster, das ein grundlegender Registerkarten-Controller mit einem Navigations-Controller für jede Registerkarte ist. Wenn es einen besseren Weg gibt, bin ich offen für Vorschläge. Vielleicht sollte ich diese Frage auch stellen.
Artilheiro


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 !?")
}

Verwenden Sie einfach navigationItem.rightBarButtonItem, wenn Sie die rechte Schaltfläche möchten
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];

2

Versuchen Sie dies. Es funktioniert für mich.

Navigationsleiste und Hintergrundbild zur rechten Schaltfläche hinzugefügt.

 UIBarButtonItem *Savebtn=[[UIBarButtonItem alloc]initWithImage:[[UIImage    
 imageNamed:@"bt_save.png"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] 
 style:UIBarButtonItemStylePlain target:self action:@selector(SaveButtonClicked)];
 self.navigationItem.rightBarButtonItem=Savebtn;

0
    UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;

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");  
}

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];
}

0

Sie sollten Ihr barButtonItem in der - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animatedMethode hinzufügen .


0

Kopieren Sie einfach diesen Objective-C-Code und fügen Sie ihn ein.

- (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
}

Ich versuche zu helfen
Vivek

0

Dieses Problem kann auftreten, wenn wir den Ansichts-Controller löschen oder versuchen, einen neuen Ansichts-Controller im Interface Builder (main.storyboard) hinzuzufügen. Um dieses Problem zu beheben, muss "Navigationselement" im neuen Ansichts-Controller hinzugefügt werden. Manchmal kommt es vor, dass wir einen neuen Bildschirm für den Ansichtscontroller erstellen und keine automatische Verbindung zu "Navigationselement" herstellen.

  1. Gehen Sie zum main.storyboard.
  2. Wählen Sie diese neue Ansicht Controller.
  3. Gehen Sie zur Dokumentskizze.
  4. Überprüfen Sie den Inhalt des View Controllers.
  5. Wenn der neue Ansichts-Controller kein Navigationselement hat, kopieren Sie das Navigationselement vom vorherigen Ansichts-Controller und fügen Sie es in den neuen Ansichts-Controller ein.
  6. Speichern und bereinigen Sie das Projekt.

0

Sie können auch mehrere Schaltflächen mit hinzufügen 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];
}

-1

@Artilheiro: Wenn es sich um ein navigationsbasiertes Projekt handelt, können Sie BaseViewController erstellen. Alle anderen Ansichten erben diese Basisansicht. In BaseView können Sie generische Methoden definieren, um die rechte Schaltfläche hinzuzufügen oder den Text der linken Schaltfläche zu ändern.

Ex:

@interface BaseController: UIViewController {

} - (void) setBackButtonCaption: (NSString *) caption;

(void) setRightButtonCaption: (NSString *) caption selectot: (SEL) selector;

@end // In BaseView.M

(void) setBackButtonCaption: (NSString *) caption {

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

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

} - (void) setRightButtonCaption: (NSString *) Untertitelauswahl: (SEL) Selektor {

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

rightButton.target= self;

[rightButton setAction:selector];

self.navigationItem.rightBarButtonItem= rightButton;

[rightButton release];

}}

Implementieren Sie jetzt in jeder benutzerdefinierten Ansicht diese Basisansicht und rufen Sie die folgenden Methoden auf:

@interface LoginView: BaseController {

In einigen Methoden rufen Sie die Basismethode auf als:

SEL sel = @selector (switchToForgotPIN);

[super setRightButtonCaption: @ "PIN vergessen" selectot: sel];

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.