Добавление одной и той же кнопки ко всем контроллерам представления в UINavigationController - PullRequest
28 голосов
/ 17 июня 2011

У меня есть UINavigationController (для использования в качестве страницы мастера), который я создаю программно, и мне нужно отобразить кнопку «Отмена», чтобы отменить процесс в любом UIViewController.

Создание UINavigationController:

FirstVC *firstVC = [[[FirstVC alloc] initWithNibName:@"FirstPage" bundle:nil] autorelease];
firstVC.delegate = self;

navigationController = [[UINavigationController alloc] initWithRootViewController:firstVC];
[self.view addSubview:navigationController.view];

Добавление кнопки отмены:

UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelRequestNewLeave:)];
navigationController.topViewController.navigationItem.rightBarButtonItem = cancelButton;
[cancelButton release];

Но когда я нажимаю вторую страницу на UINavigationController, кнопка отмены не отображается на UINavigationBar. Если я вернусь на первую страницу, кнопка отмены есть. Так что, видимо, кнопка добавлена ​​только для первого просмотра. Я полагаю, что это потому, что я не делаю подклассы UINavigationController, потому что мне нужно использовать это в подпредставлении. Но я не знаю, как установить rightBarButtonItem в UINavigationController, который создается программно.

navigationController.topViewController.navigationItem.rightBarButtonItem = cancelButton;

Может кто-нибудь пролить свет на это?

Заранее спасибо.

Ответы [ 8 ]

41 голосов
/ 17 июня 2011

Элемент навигации для каждого контроллера представления. Панель навигации извлекает свое содержимое из элемента навигации контроллера представления, вид которого он в данный момент создает, что соответствует контроллеру представления в верхней части стека контроллера навигации.

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

  • Скопируйте и вставьте код во все соответствующие контроллеры представления.
  • Переместите код в служебную функцию или класс и вызовите его.
  • Создание общего суперкласса для всех соответствующих контроллеров представления, который обрабатывает настройку кнопки отмены для своих подклассов.
22 голосов
/ 27 августа 2014

Вы также можете создать подкласс UINavigationcontroller и переопределить несколько таких методов:

- (id)initWithRootViewController:(UIViewController *)rootViewController {
    self = [super initWithRootViewController:rootViewController];
    if (self) {
        [self setCloseButtonToController:rootViewController];
    }
    return self;
}

- (void)dismissController {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)setCloseButtonToController:(UIViewController *)viewController {
    UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(dismissController)];
    [viewController.navigationItem setRightBarButtonItem:closeItem];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    [super pushViewController:viewController animated:animated];

    [self setCloseButtonToController:viewController];

}
8 голосов
/ 17 июня 2011

Вместо этого вы можете принять протокол UINavigationControllerDelegate в классе, который создает экземпляр UINavigationController.Вы также можете заранее создать cancelButton и затем реализовать navigationController:willShowViewController:animated: следующим образом:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    viewController.navigationItem.rightBarButtonItem = cancelButton;
}

. Вам нужно будет помнить, что нужно создать и удерживать cancelButton, а не выпускать его.Это также будет означать, что cancelRequestNewLeave: должен быть методом в классе, который создает экземпляр UINavigationController, который, как я полагаю, сейчас есть.

5 голосов
/ 07 октября 2015
  1. создать CommonViewController
  2. создать FirstViewController ( расширяется от CommonViewController )
  3. create SecondeViewController ( расширяется от CommonViewController )
  4. добавить общие функции в CommonViewController

вот так

CommonViewController.h

@interface CommonViewController : UIViewController

-(void) initializeCartBarButton;

@end

CommonViewController.m

#import "CommonViewController.h"

@interface CommonViewController ()

@end

@implementation CommonViewController

-(void) initializeCartBarButton {


    UIBarButtonItem *cartBarButton = [[UIBarButtonItem alloc] init];
    cartBarButton.title = @"cart";
    [cartBarButton setTarget: self];
    [cartBarButton setAction: @selector(goToCart:)];

    self.navigationItem.rightBarButtonItem = cartBarButton;
    }

- (IBAction) goToCart:(id)sender {
    NSLog(@"");
  }

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
  }

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
  }

@end

FirstViewController.h

#import <UIKit/UIKit.h>
#import "CommonViewController.h"

@interface FirstViewController : CommonViewController

@end

FirstViewController.m

#import "FirstViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initializeCartBarButton];
}
@end

SecondViewController.h

#import <UIKit/UIKit.h>
#import "CommonViewController.h"

@interface SecondViewController : CommonViewController

@end

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initializeCartBarButton];
}
@end

примечание: вы можете добавить код initializeCartBarButton в viewDidLoad CommonViewController и удалить эту функцию из CommonViewController и из дочернего класса

3 голосов
/ 21 июня 2016

Вот как я это сделал с подклассом UINavigationController, способным отбрасывать каждый viewController, вставленный в него.

class CustomNavigationController: UINavigationController, UINavigationControllerDelegate{

    //TODO: Use when we have more right bar button types.
    var rightBarButtonType: RightBarButtonType = .Close

    enum RightBarButtonType{
        case Close
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    // MARK: Private Functions
    private func addRightBarButtonTo(viewController: UIViewController){

        let barButtonItem: UIBarButtonItem!
        switch self.rightBarButtonType {
        case .Close:
            barButtonItem = UIBarButtonItem(image: UIImage(named: "ic_close_white"), style: .Done, target: self, action: #selector(CustomNavigationController.dismiss(_:)))

        }
        viewController.navigationItem.rightBarButtonItem = barButtonItem
    }

    // MARK: UINavigationController Delegate
    func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        self.addRightBarButtonTo(viewController)
    }

    @objc func dismiss(sender: AnyObject){
        self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
    }
}
1 голос
/ 17 июня 2011

Вам нужно будет добавить кнопку в каждом контроллере представления.Вы не можете сделать это, установив один раз или разделив один между контроллерами представления (разумным способом).Хорошее место для добавления кнопки - метод viewDidLoad ваших контроллеров представления.Вы можете создать для них один базовый подкласс UIViewConteoller, если считаете, что это повторяется.

0 голосов
/ 12 января 2014

Добавьте этот код в ваш метод viewDidLoad rootview и внедрите cancelMethod в контроллере rootview. Он будет доступен во всех контроллерах представления.Вы можете отрегулировать расположение кнопки, изменив рамку кнопки. Для изменения ориентации вы вручную отрегулируете расположение кнопки.

 UIButton *btnCancel = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [btnCancel addTarget:self
                        action:@selector(cancelMethod)
              forControlEvents:UIControlEventTouchDown];
        [btnCancel setBackgroundImage:[UIImage imageNamed:@"image"]  
        forState:UIControlStateNormal];
        btnCancel.frame = CGRectMake(280, 27, 45, 25);

    [self.navigationController.view addSubview: btnCancel];
0 голосов
/ 17 июня 2011

Вы можете добавить пользовательскую кнопку UIB «Отмена» непосредственно в представление NavigationBar вместо использования UIBarButtonItem.

UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
cancelButton.imageView = // Some custom image
cancelButton.frame = CGRectMake(...);  // Something far to the right.
[self.navigationController.navigationBar addSubview: cancelButton];

Обычный способ сделать это - добавить эту кнопку отмены в навигационный элемент каждого отдельного контроллера представления в вашем стеке навигации. Вышеупомянутый подход может упростить его, позволив вам писать меньше кода, но это всего лишь крошечный хак.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...