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

发布于 2024-11-16 05:56:08 字数 1212 浏览 2 评论 0原文

我有一个以编程方式创建的 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,因为我需要在子视图中使用它。但我不知道如何在以编程方式创建的 UINavigationController 中设置 rightBarButtonItem 。

navigationController.topViewController.navigationItem.rightBarButtonItem = cancelButton;

有人可以阐明这一点吗?

提前致谢。

I have a UINavigationController (to use like a wizard page) which I create programmatically and I need to display a "Cancel" button to cancel the process in any UIViewController.

Creating the UINavigationController:

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

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

Adding Cancel Button:

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

But when I push a second page to UINavigationController the cancel button is not shown on the UINavigationBar. If I go back to first page, the cancel button is there. So, apparently the button is added only for the first view. I believe this is because I'm not subclassing UINavigationController, because I need to use it in a subview. But I don't know how to set the rightBarButtonItem in a UINavigationController which is created programmatically.

navigationController.topViewController.navigationItem.rightBarButtonItem = cancelButton;

Can someone shed a light on this?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

孤独难免 2024-11-23 05:56:08

导航项是每个视图控制器的。导航栏从当前正在构建其视图的视图控制器的导航项中绘制其内容,该视图控制器对应于导航控制器堆栈顶部的视图控制器。

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

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

The navigation item is per view controller. The navigation bar draws its contents from the navigation item of the view controller whose view it's currently framing, which corresponds to the view controller at the top of the navigation controller's stack.

You basically need each view controller to stick a cancel button in its navigation item. You can do any of the following:

  • Copy-paste the code into all relevant view controllers.
  • Move the code into a utility function or class and call that.
  • Create a common superclass for all relevant view controllers that handles setting up the cancel button for its subclasses.
灯角 2024-11-23 05:56:08

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

}

You can also subclass UINavigationcontroller and overide few methods like this:

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

}
为人所爱 2024-11-23 05:56:08

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

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

您必须记住创建并按住 cancelButton code> 并且不释放它。这也意味着 cancelRequestNewLeave: 必须是类中的一个方法,用于创建 UINavigationController 实例,我猜这就是现在的情况。

You can instead adopt the UINavigationControllerDelegate protocol in the class which creates the UINavigationController instance. You can also create the cancelButton in advance and then implement navigationController:willShowViewController:animated: like this,

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

You will have to remember to create and hold the cancelButton and not release it. This will also mean cancelRequestNewLeave: will have to be a method in class that creates the UINavigationController instance which is what it is right now I guess.

岛徒 2024-11-23 05:56:08
  1. 创建 CommonViewController
  2. 创建 FirstViewController (从 CommonViewController 扩展)
  3. 创建 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

注意:可以在CommonViewController的viewDidLoad中添加initializeCartBarButton的代码,并从CommonViewController及其子类中删除该函数

  1. create CommonViewController
  2. create FirstViewController (extends from CommonViewController)
  3. create SecondeViewController (extends from CommonViewController)
  4. add function common functions in the CommonViewController

like that

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

note: you can add the code of initializeCartBarButton in the viewDidLoad of CommonViewController and delete this fuction from CommonViewController and from child class's

烏雲後面有陽光 2024-11-23 05:56:08

这就是我使用 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)
    }
}

This is how I did it with UINavigationController subclass that is capable of dismissing every viewController pushed into it.

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)
    }
}
难以启齿的温柔 2024-11-23 05:56:08

您需要在每个视图控制器中添加按钮。您不能通过设置一次或在视图控制器之间共享一个(以合理的方式)来做到这一点。添加按钮的好地方是视图控制器的 viewDidLoad 方法。如果您觉得这有点重复,您可以为它们创建一个基本的 UIViewConteoller 子类。

You'll need to add the button in every view controller. You cannot do it by setting one once or sharing one between view controllers (in a sensible fashion). A good place to add the button is in the viewDidLoad method of your view controllers. You can create one basic UIViewConteoller subclass for them if you feel this gets to repetitive.

在梵高的星空下 2024-11-23 05:56:08

您可以将自定义“取消”UIButton 直接添加到导航栏的视图中,而不是使用 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 中。上述方法可以让您编写更少的代码,从而使其变得更简单,但它是一个小技巧。

You can add a custom 'Cancel' UIButton directly to the NavigationBar's view instead of using the UIBarButtonItem.

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

The normal way to do this is to add that cancel button to the navigationItem of every single view controller in your navigation stack. The above approach can make it simpler by allowing you to write less code, but it is a tiny bit of a hack.

时间海 2024-11-23 05:56:08

将此代码添加到您的 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];

Add this code in your rootview viewDidLoad method and implement the cancelMethod in rootview controller.This will be available in all the view controllers. you can adjust the button location by changing button frame.For orientation change you have manually adjust the location of button.

 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];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文