在UINavigationController中为所有视图控制器添加相同的按钮
我有一个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
时, UINavigationController
上没有显示取消按钮。 如果我回到第一页,取消按钮就在那里。 所以,显然只为第一个视图添加了按钮。 我相信这是因为我不是UINavigationController
子类,因为我需要在子视图中使用它。 但我不知道如何在以编程方式创建的UINavigationController
设置rightBarButtonItem
。
navigationController.topViewController.navigationItem.rightBarButtonItem = cancelButton;
有人能否对此有所了解?
提前致谢。
导航项是每个视图控制器。 导航栏从视图控制器的导航项中绘制其内容,该视图控制器的当前框架视图对应于导航控制器堆栈顶部的视图控制器。
您基本上需要每个视图控制器在其导航项中粘贴取消按钮。 您可以执行以下任何操作:
- 将代码复制粘贴到所有相关的视图控制器中。
- 将代码移动到实用程序函数或类中并调用它。
- 为所有相关视图控制器创建一个公共超类,用于处理为其子类设置取消按钮。
您还可以将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]; }
您可以在创建UINavigationController
实例的类中采用UINavigationControllerDelegate
协议。 你也可以提前创建cancelButton
,然后实现navigationController:willShowViewController:animated:
像这样,
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { viewController.navigationItem.rightBarButtonItem = cancelButton; }
你必须记住创建并保持cancelButton
而不是释放它。 这也意味着cancelRequestNewLeave:
必须是类中创建UINavigationController
实例的方法,这是我现在的想法。
- 创建CommonViewController
- 创建FirstViewController( 从CommonViewController扩展 )
- 创建SecondeViewController( 从CommonViewController扩展 )
- 在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 #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 #import "CommonViewController.h" @interface SecondViewController : CommonViewController @end
SecondViewController.m
#import "SecondViewController.h" @interface SecondViewController () @end @implementation SecondViewController - (void)viewDidLoad { [super viewDidLoad]; [self initializeCartBarButton]; } @end
注意:您可以在CommonViewController的viewDidLoad中添加initializeCartBarButton的代码,并从CommonViewController和子类中删除此function
这就是我使用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) } }
您需要在每个视图控制器中添加按钮。 你不能通过设置一次或在视图控制器之间共享一个(以合理的方式)来做到这一点。 添加按钮的好地方是视图控制器的viewDidLoad方法。 如果您觉得这会重复,可以为它们创建一个基本的UIViewConteoller子类。
您可以将自定义“取消”UIButton直接添加到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];
执行此操作的常规方法是将取消按钮添加到导航堆栈中每个视图控制器的navigationItem。 上面的方法可以通过允许你编写更少的代码来简化它,但它只是一点点破解。
在rootview viewDidLoad方法中添加此代码,并在rootview控制器中实现cancelMethod。这将在所有视图控制器中可用。 您可以通过更改按钮框来调整按钮位置。对于方向更改,您可以手动调整按钮的位置。
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];