Как добавить правую кнопку в UINavigationController?

191

Я пытаюсь добавить кнопку обновления в верхнюю панель контроллера навигации, но безуспешно.

Вот заголовок:

@interface PropertyViewController : UINavigationController {

}

Вот как я пытаюсь добавить это:

- (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
источник

Ответы:

362

Попробуйте сделать это в viewDidLoad. Как правило, в любом случае вам следует отложить все, что вы можете, до этого момента, когда UIViewController включается, до его отображения может пройти довольно много времени, и нет смысла делать работу раньше и связывать память.

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

Что касается того, почему это не работает в настоящее время, я не могу сказать со 100% -ной уверенностью, не увидев больше кода, но многое происходит между init и загрузкой представления, и вы можете делать что-то, что приводит к сбросу навигационного элемента между.

Луи Гербарг
источник
45
Если вы делаете это вне подкласса UINavigationController, вы можете ссылаться на него следующим образом: someNavController.topLevelController.navigationItem.rightBarButtonItem = anotherButton
ransomweaver
2
Я реализовывал предложенное решение, и мое приложение продолжало падать, пока я не понял, что имя метода @selector должно заканчиваться двоеточием (:).
Стелс
10
Даже внутри метода viewDidLoad из UINavigationContoller мне приходилось вызывать его следующим образомself.topViewController.navigationItem.leftBarButtonItem = nextButton;
Joseph
Спасибо! @ Джозеф, Ваше разъяснение спасло меня. (у) :)
Прасанна
38

Попробуйте добавить кнопку в навигационный элемент контроллера представления, который будет помещен в PropertyViewControllerсозданный вами класс.

То есть:

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

Теперь эта информационная кнопка, созданная программно, будет отображаться на панели навигации. Идея состоит в том, что навигационный контроллер получает информацию об отображении (название, кнопки и т. Д.) Из того, UIViewControllerчто он собирается отобразить. Вы на самом деле не добавляете кнопки и тому подобное прямо в UINavigationController.

Адам
источник
2
Установка rightBarButtonItem непосредственно на UINavigationController не работает для меня (как предложено Луи Гербаргом выше). Вместо этого установка элемента непосредственно на UIViewController под рукой, как советует Адем, сработала!
Левиафан
4
+1 за «Попробуйте добавить кнопку в навигационный элемент контроллера представления, который будет перемещен» !
Кюлы,
25

Кажется, что некоторые люди (как я) могут прийти сюда в поисках того, как добавить кнопку панели навигации в Интерфейсном Разработчике. Ответ ниже показывает, как это сделать.

Добавьте навигационный контроллер на вашу раскадровку

Выберите View Controller, а затем в меню Xcode выберите « Редактор»> «Встроить»> «Navigation Controller» .

введите описание изображения здесь

В качестве альтернативы, вы можете добавить UINavigationBar из библиотеки объектов.

Добавить элемент панели кнопок

Перетащите a UIBarButtonItemиз библиотеки объектов на верхнюю панель навигации.

введите описание изображения здесь

Это должно выглядеть так:

введите описание изображения здесь

Установить атрибуты

Вы можете дважды щелкнуть «Элемент», чтобы изменить текст на что-то вроде «Обновить», но есть фактический значок « Обновить», который вы можете использовать. Просто выберите Инспектор атрибутов, UIBarButtonItemа для пункта «Система» выберите « Обновить» .

введите описание изображения здесь

Это даст вам значок обновления по умолчанию.

введите описание изображения здесь

Добавить действие IB

Перетащите управление из в UIBarButtonItemView Controller, чтобы добавить @IBAction.

class ViewController: UIViewController {

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

Вот и все.

Suragch
источник
Извините, я не совсем понимаю, о чем вы говорите. Попробуйте создать новый вопрос с изображением, иллюстрирующим то, о чем вы говорите. Затем добавьте ссылку на него здесь.
Сурагч
@Suragch, как я могу делать то же самое с файлами XIB вместо раскадровок? Спасибо
Кристиан Чапарро А.
@CristianChaparroA. Обычно файлы XIB предназначены для отдельных видов, а панель навигации (в которой размещены элементы кнопок панели) - для нескольких видов. Я никогда не использовал xib с элементами кнопок бара. Вы можете попробовать задать новый вопрос, а затем дать ссылку на него здесь.
Сурагч
14

По умолчанию есть системная кнопка «Обновить»:

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

Вы можете использовать это:

Objective-C

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

стриж

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

}
Гаурав Гилани
источник
Может кто-нибудь сказать мне, есть ли вред делать это в ViewWillAppear вместо ViewDidLoad
Ниранджан Молкери
6

Для быстрой 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
источник
Я бы порекомендовал использовать новый селектор swift2: #selector (classname.functionname)
Emptyless
5

Вот решение в Swift (установите необходимые параметры):

var optionButton = UIBarButtonItem()
optionButton.title = "Settings"
//optionButton.action = something (put your action here)
self.navigationItem.rightBarButtonItem = optionButton
vontell
источник
4

Почему вы подклассы UINavigationController? Нет необходимости создавать его подкласс, если все, что вам нужно сделать, это добавить к нему кнопку.

Установите иерархию с UINavigationControllerверхним знаком, а затем в viewDidLoad:методе вашего корневого контроллера : установите кнопку и присоедините ее к элементу навигации, вызвав

[[self navigationItem] setRightBarButtonItem:myBarButtonItem];
Jasarien
источник
1
Это хороший вопрос. То, что я пытаюсь сделать, это на самом деле очень распространенный шаблон проектирования, который представляет собой базовый контроллер вкладок с контроллером навигации для каждой вкладки. Если есть лучший способ, я открыт для предложений. Может быть, я тоже должен задать этот вопрос.
Artilheiro
4

Можешь попробовать

self.navigationBar.topItem.rightBarButtonItem = anotherButton;
user2999133
источник
Работал как шарм :)
Саурабх Бхатия
3

Свифт 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
источник
Просто используйте navigationItem.rightBarButtonItem, если вы хотите кнопку с правой стороны
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
источник
2

Попробуйте это. Это работает для меня.

Панель навигации, а также добавил фоновое изображение для правой кнопки.

 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");  
}
tv.ashvin
источник
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
источник
0

Вы должны добавить свой barButtonItem в - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animatedметод.

Retik
источник
0

Просто скопируйте и вставьте этот код 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
}
Вивек
источник
Я пытаюсь помочь
Вивек
0

Эта проблема может возникнуть, если мы удалим контроллер представления или попытаемся добавить новый контроллер представления внутри компоновщика интерфейса (main.storyboard). Чтобы решить эту проблему, требуется добавить «Элемент навигации» внутри нового контроллера представления. Иногда случается, что мы создаем новый экран контроллера представления, и он не подключается к «Элементу навигации» автоматически.

  1. Перейти на main.storyboard.
  2. Выберите этот новый вид контроллера.
  3. Перейти к схеме документа.
  4. Проверьте просмотр содержимого контроллера.
  5. Если новый контроллер представления не имеет элемента навигации, скопируйте элемент навигации из предыдущего контроллера просмотра и вставьте его в новый контроллер представления.
  6. сохранить и очистить проект.
NilamK
источник
0

Также вы можете добавить несколько кнопок, используя 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
источник
-1

@Artilheiro: Если это проект на основе навигации, вы можете создать BaseViewController. Все остальные представления будут наследовать этот BaseView. В BaseView вы можете определить общие методы, чтобы добавить правую кнопку или изменить текст левой кнопки.

например:

@interface BaseController: UIViewController {

} - (void) setBackButtonCaption: (NSString *) заголовок;

(void) setRightButtonCaption: (NSString *) заголовок selectot: (SEL) селектор;

@end // В BaseView.M

(void) setBackButtonCaption: (NSString *) caption {

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

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

} - (void) setRightButtonCaption: (NSString *) заголовок selectot: (SEL) селектор {

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

rightButton.target= self;

[rightButton setAction:selector];

self.navigationItem.rightBarButtonItem= rightButton;

[rightButton release];

}

И теперь в любом настраиваемом представлении реализуйте это базовое представление, вызывая методы:

@interface LoginView: BaseController {

В некоторых методах вызов базового метода как:

SEL sel = @selector (switchToForgotPIN);

[super setRightButtonCaption: @ "Забыл PIN-код" selectot: sel];

iPhoneDev
источник