在UINavigationController中为所有视图控制器添加相同的按钮

Oza*_*zay 29 iphone uinavigationcontroller ios

我有一个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];
Run Code Online (Sandbox Code Playgroud)

添加取消按钮:

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

但当我按下第二页时UINavigationController,取消按钮上没有显示UINavigationBar.如果我回到第一页,取消按钮就在那里.所以,显然该按钮仅为第一个视图添加.我相信这是因为我不是子类UINavigationController,因为我需要在子视图中使用它.但我不知道如何设置rightBarButtonItemUINavigationController其中编程方式创建.

navigationController.topViewController.navigationItem.rightBarButtonItem = cancelButton;
Run Code Online (Sandbox Code Playgroud)

有人可以对此有所了解吗?

提前致谢.

Jer*_*man 42

导航项是每个视图控制器.导航栏从视图控制器的导航项中绘制其内容,该视图控制器的当前框架视图对应于导航控制器堆栈顶部的视图控制器.

您基本上需要每个视图控制器在其导航项中粘贴取消按钮.您可以执行以下任何操作:

  • 将代码复制粘贴到所有相关的视图控制器中.
  • 将代码移动到实用程序函数或类中并调用它.
  • 为所有相关视图控制器创建一个公共超类,用于处理为其子类设置取消按钮.

  • 虽然是迟到的评论,但您应该避免通过超类为类提供功能.在开发的后期,您可能会有一些控制器子类,它们不会"喜欢"继承额外的功能.不仅如此,您的代码可能会变得更加复杂. (2认同)

小智 22

您还可以子类化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];

}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。我正在模态地呈现一个“ UINavigationController”,我希望有一个简单的“取消”按钮可以应用于其中的所有屏幕。显然,我的用例对Google来说非常困难,而且不受欢迎。 (2认同)

Dee*_*olu 8

您可以UINavigationControllerDelegate在创建UINavigationController实例的类中采用协议.您也可以cancelButton提前创建,然后navigationController:willShowViewController:animated:像这样实现,

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

您将不得不记住创建并保留它cancelButton而不是释放它.这也意味着cancelRequestNewLeave:必须是类中创建UINavigationController实例的方法,这正是我现在所想的.


Moh*_*ami 5

  1. 创建CommonViewController
  2. 创建FirstViewController(从CommonViewController扩展)
  3. 创建SecondeViewController(从CommonViewController扩展)
  4. 在CommonViewController中添加函数常用函数

像那样

CommonViewController.h

@interface CommonViewController : UIViewController

-(void) initializeCartBarButton;

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

FirstViewController.h

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

@interface FirstViewController : CommonViewController

@end
Run Code Online (Sandbox Code Playgroud)

FirstViewController.m

#import "FirstViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initializeCartBarButton];
}
@end
Run Code Online (Sandbox Code Playgroud)

SecondViewController.h

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

@interface SecondViewController : CommonViewController

@end
Run Code Online (Sandbox Code Playgroud)

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initializeCartBarButton];
}
@end
Run Code Online (Sandbox Code Playgroud)

注意:您可以在CommonViewController的viewDidLoad中添加initializeCartBarButton的代码,并从CommonViewController和子类中删除此功能


Mad*_*Nik 5

这就是我使用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)
    }
}
Run Code Online (Sandbox Code Playgroud)