ios 向 UINavigationController 中的所有视图控制器添加相同的按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6389094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding same button to all view controllers in UINavigationController
提问by Ozay
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
.
我有一个UINavigationController
(像向导页面一样使用),我以编程方式创建,我需要显示一个“取消”按钮来取消任何UIViewController
.
Creating the UINavigationController
:
创建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.
但是当我将第二页推到UINavigationController
取消按钮时,UINavigationBar
. 如果我回到第一页,取消按钮就在那里。因此,显然该按钮仅针对第一个视图添加。我相信这是因为我没有子类化UINavigationController
,因为我需要在子视图中使用它。但我不知道如何设置以编程方式创建的rightBarButtonItem
in UINavigationController
。
navigationController.topViewController.navigationItem.rightBarButtonItem = cancelButton;
Can someone shed a light on this?
有人可以解释一下吗?
Thanks in advance.
提前致谢。
回答by Jeremy W. Sherman
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.
- 将代码复制粘贴到所有相关的视图控制器中。
- 将代码移动到实用程序函数或类中并调用它。
- 为所有相关的视图控制器创建一个公共超类,用于为其子类设置取消按钮。
回答by Rafa? Wójcik
You can also subclass UINavigationcontroller
and overide few methods like this:
你也可以子类化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];
}
回答by Deepak Danduprolu
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,
您可以改为采用UINavigationControllerDelegate
创建UINavigationController
实例的类中的协议。您也可以cancelButton
提前创建,然后navigationController:willShowViewController:animated:
像这样实现,
- (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.
您必须记住创建并持有cancelButton
而不是释放它。这也意味着cancelRequestNewLeave:
必须是类中的一个方法来创建UINavigationController
实例,我猜这就是它现在的样子。
回答by Mohamad Chami
- create CommonViewController
- create FirstViewController (extends from CommonViewController)
- create SecondeViewController (extends from CommonViewController)
- add function common functions in the CommonViewController
- 创建 CommonViewController
- 创建 FirstViewController (从 CommonViewController 扩展)
- 创建 SecondeViewController (从 CommonViewController 扩展)
- 在 CommonViewController 中添加函数常用函数
like that
像那样
CommonViewController.h
通用视图控制器.h
@interface CommonViewController : UIViewController
-(void) initializeCartBarButton;
@end
CommonViewController.m
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
第一视图控制器.h
#import <UIKit/UIKit.h>
#import "CommonViewController.h"
@interface FirstViewController : CommonViewController
@end
FirstViewController.m
第一视图控制器.m
#import "FirstViewController.h"
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initializeCartBarButton];
}
@end
SecondViewController.h
第二视图控制器.h
#import <UIKit/UIKit.h>
#import "CommonViewController.h"
@interface SecondViewController : CommonViewController
@end
SecondViewController.m
第二视图控制器.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
注意:可以在 CommonViewController 的 viewDidLoad 中添加 initializeCartBarButton 的代码,并从 CommonViewController 和子类的
回答by MadNik
This is how I did it with UINavigationController
subclass that is capable of dismissing every viewController pushed into it.
这就是我如何使用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)
}
}
回答by Johan Kool
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.
您需要在每个视图控制器中添加按钮。您不能通过设置一次或在视图控制器之间共享一个(以一种明智的方式)来做到这一点。添加按钮的好地方是在视图控制器的 viewDidLoad 方法中。如果您觉得这变得重复,您可以为它们创建一个基本的 UIViewConteoller 子类。
回答by hundreth
You can add a custom 'Cancel' UIButton directly to the NavigationBar's view instead of using the UIBarButtonItem.
您可以将自定义的“取消”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];
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.
执行此操作的正常方法是将取消按钮添加到导航堆栈中每个视图控制器的导航项中。通过允许您编写更少的代码,上述方法可以使其更简单,但它是一个小技巧。
回答by Roshan
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.
将此代码添加到您的 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];