Jak dodać odpowiedni przycisk do UINavigationController?

191

Próbuję dodać przycisk odświeżania do górnego paska kontrolera nawigacji bez powodzenia.

Oto nagłówek:

@interface PropertyViewController : UINavigationController {

}

Oto jak próbuję to dodać:

- (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
źródło

Odpowiedzi:

362

Spróbuj to zrobić w viewDidLoad. Ogólnie rzecz biorąc, powinieneś odłożyć wszystko, co możesz, do tego momentu, kiedy zostanie uruchomiony UIViewController, może jeszcze upłynąć trochę czasu, zanim zostanie wyświetlony, nie ma sensu wcześnie wykonywać pracy i wiązać pamięci.

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

Jeśli chodzi o to, dlaczego obecnie nie działa, nie mogę powiedzieć ze 100% pewnością, że nie widzę więcej kodu, ale między inicjacją a ładowaniem widoku dzieje się wiele rzeczy, a możesz robić coś, co powoduje zresetowanie elementu Nawigacja pomiędzy.

Louis Gerbarg
źródło
45
Jeśli robisz to poza podklasą UINavigationController, powinieneś to tak nazwać: someNavController.topLevelController.navigationItem.rightBarButtonItem = anotherButton
ransomweaver
2
Wdrażałem sugerowane rozwiązanie, a moja aplikacja ulegała awarii, dopóki nie zdałem sobie sprawy, że nazwa metody @selector musi kończyć się dwukropkiem (:).
Stealth
10
Nawet w metodzie viewDidLoad obiektu UINavigationContoller musiałem to nazwaćself.topViewController.navigationItem.leftBarButtonItem = nextButton;
Joseph
Dzięki! @Joseph, Twoje wyjaśnienie mnie uratowało. (y) :)
Prasanna
38

Spróbuj dodać przycisk do elementu nawigacji kontrolera widoku, który ma zostać wypchnięty na PropertyViewControllerutworzoną przez ciebie klasę.

To jest:

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

Teraz ten przycisk info, który został utworzony programowo, pojawi się na pasku nawigacyjnym. Chodzi o to, że kontroler nawigacyjny pobiera informacje o wyświetlaniu (tytuł, przyciski itp.) Z tego UIViewController, co ma zamiar wyświetlić. Tak naprawdę nie dodajesz przycisków i tak bezpośrednio do UINavigationController.

Adam
źródło
2
Ustawienie rightBarButtonItem bezpośrednio na UINavigationController nie działało dla mnie (jak zaproponował Louis Gerbarg powyżej). Zamiast tego ustawić element bezpośrednio na UIViewController pod ręką, jak sugeruje Adem, działał!
leviathan
4
+1 dla „Spróbuj dodać przycisk do elementu nawigacyjnego kontrolera widoku, który ma zostać wypchnięty” !
Kjuly
25

Wygląda na to, że niektórzy ludzie (jak ja) mogą tu przyjechać i szukać sposobu dodania przycisku paska nawigacji w Konstruktorze interfejsów. Poniższa odpowiedź pokazuje, jak to zrobić.

Dodaj kontroler nawigacji do swojej Storyboard

Wybierz widok kontrolera, a następnie w menu Xcode wybierz polecenie Edytor> Osadź w> Kontroler nawigacji .

wprowadź opis zdjęcia tutaj

Alternatywnie możesz dodać UINavigationBarz biblioteki obiektów.

Dodaj element przycisku paska

Przeciągnij a UIBarButtonItemz biblioteki obiektów na górny pasek nawigacyjny.

wprowadź opis zdjęcia tutaj

To powinno wyglądać tak:

wprowadź opis zdjęcia tutaj

Ustaw atrybuty

Możesz dwukrotnie kliknąć „Element”, aby zmienić tekst na coś w rodzaju „Odśwież”, ale istnieje odpowiednia ikona Odśwież , której możesz użyć. Wystarczy wybrać Inspektora atrybutów dla UIBarButtonItemi dla pozycji systemu wybierz Odśwież .

wprowadź opis zdjęcia tutaj

To da domyślną ikonę Odśwież.

wprowadź opis zdjęcia tutaj

Dodaj akcję IB

Przeciągnij i przeciągnij z UIBarButtonItemkontrolera widoku, aby dodać @IBAction.

class ViewController: UIViewController {

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

Otóż ​​to.

Suragch
źródło
Przepraszam, nie do końca rozumiem, o czym mówisz. Spróbuj zrobić nowe pytanie z obrazem ilustrującym to, o czym mówisz. Dodaj link do tego tutaj.
Suragch
@Suragch, jak mogę zrobić to samo z plikami XIB zamiast scenariuszy? , dzięki
Cristian Chaparro A.,
@CristianChaparroA. Zwykle pliki Xib dotyczą pojedynczych widoków, a pasek nawigacyjny (który obsługuje elementy przycisku paska) służy do wielu widoków. Nigdy nie używałem xib z elementami przycisku paska. Możesz spróbować zadać nowe pytanie, a następnie link do niego tutaj.
Suragch
14

Domyślny przycisk systemowy „Odśwież”:

- (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
źródło
11

Możesz użyć tego:

Cel C

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

Szybki

let rightSideOptionButton = UIBarButtonItem()
rightSideOptionButton.title = "Right"
self.navigationItem.rightBarButtonItem = rightSideOptionButton
Vandit Mehta
źródło
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
źródło
Czy ktoś może mi powiedzieć, czy jest coś złego w robieniu tego w ViewWillAppear zamiast ViewDidLoad
Niranjan Molkeri
6

Dla szybkiego 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
źródło
Poleciłbym użycie nowego selektora swift2: #selector (classname.functionname)
Emptyless
5

Oto rozwiązanie w Swift (ustaw opcje w razie potrzeby):

var optionButton = UIBarButtonItem()
optionButton.title = "Settings"
//optionButton.action = something (put your action here)
self.navigationItem.rightBarButtonItem = optionButton
Vontell
źródło
4

Dlaczego jesteście podklasami UINavigationController? Nie ma potrzeby dzielenia go, jeśli wszystko, co musisz zrobić, to dodać do niego przycisk.

Ustaw hierarchię UINavigationControlleru góry, a następnie w viewDidLoad:metodzie kontrolera widoku głównego : ustaw przycisk i dołącz go do elementu nawigacyjnego, wywołując

[[self navigationItem] setRightBarButtonItem:myBarButtonItem];
Jasarien
źródło
1
To jest dobre pytanie. To, co próbuję zrobić, to w rzeczywistości bardzo powszechny wzorzec projektowy, który jest podstawowym kontrolerem kart z kontrolerem nawigacji dla każdej karty. Jeśli istnieje lepszy sposób, jestem otwarty na sugestie. Może powinienem też zadać to pytanie.
Artilheiro,
4

Możesz spróbować

self.navigationBar.topItem.rightBarButtonItem = anotherButton;
użytkownik2999133
źródło
Działa jak urok :)
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
źródło
Wystarczy użyć navigationItem.rightBarButtonItem, jeśli chcesz przycisk po prawej stronie
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
źródło
2

Spróbuj tego. To działa dla mnie.

Pasek nawigacji, a także dodano obraz tła do prawego przycisku.

 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
źródło
0
    UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;
Mahesh Aswathanarayana
źródło
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
źródło
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
źródło
0

Powinieneś dodać swój barButtonItem w - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animatedmetodzie.

Retik
źródło
0

Po prostu skopiuj i wklej ten kod Celu 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
źródło
Próbuję pomóc
Vivek
0

Ten problem może wystąpić, jeśli usuniemy kontroler widoku lub spróbujemy dodać nowy kontroler widoku w narzędziu do tworzenia interfejsów (main.storyboard). Aby rozwiązać ten problem, konieczne jest dodanie „elementu nawigacyjnego” w nowym kontrolerze widoku. Czasami zdarza się, że tworzymy nowy ekran kontrolera widoku i nie łączy się on automatycznie z „Elementem nawigacji”.

  1. Idź do main.storyboard.
  2. Wybierz nowy widok Kontroler.
  3. Przejdź do konspektu dokumentu.
  4. Sprawdź widok Treść kontrolera.
  5. Jeśli nowy kontroler widoku nie ma elementu nawigacyjnego, skopiuj element nawigacyjny z poprzedniego kontrolera widoku i wklej go do nowego kontrolera widoku.
  6. zapisz i wyczyść projekt.
NilamK
źródło
0

Możesz także dodawać wiele przycisków za pomocą 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
źródło
-1

@Artilheiro: Jeśli jest to projekt oparty na nawigacji, możesz utworzyć BaseViewController. Wszystkie inne widoki odziedziczą ten BaseView. W BaseView możesz zdefiniować ogólne metody dodawania prawego przycisku lub zmiany tekstu lewego przycisku.

dawny:

@interface BaseController: UIViewController {

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

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

@end // W BaseView.M

(void) setBackButtonCaption: (NSString *) caption {

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

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

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

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

rightButton.target= self;

[rightButton setAction:selector];

self.navigationItem.rightBarButtonItem= rightButton;

[rightButton release];

}

A teraz w dowolnym widoku niestandardowym zaimplementuj ten widok podstawowy:

@interface LoginView: BaseController {

W niektórych metodach metoda bazowa wywołuje jako:

SEL sel = @selector (switchToForgotPIN);

[super setRightButtonCaption: @ „Forgot PIN” selectot: sel];

iPhoneDev
źródło