![](/img/trans.png)
[英]access UINavigationController from subclass of UINavigationBar
[英]How to subclass UINavigationBar for a UINavigationController programmatically?
我正在使用自定义 drawRect function 在 iOS4 的应用程序中的UINavigationBar
上绘图,它不使用图像,仅使用 CoreGraphics。
由于您无法在 iOS5 的UINavigationBar
类别中实现 drawRect,因此 Apple 建议继承UINavigationBar
。
当navigationBar
属性为只读时,如何用UINavigationController
中的子类替换UINavigationBar
(因此它将与 iOS4 和 iOS5 兼容)?
@property(nonatomic, readonly) UINavigationBar *navigationBar
我根本没有在我的应用程序中使用 XIB,因此将UINavigationBar
添加到 NIB 并通过 InterfaceBuilder 更改 class 不是一种选择。
在 iOS 6 中,他们向UINavigationController
添加了一种新方法,该方法在 iOS 5 中也可收回:
- (id)initWithNavigationBarClass:(Class)navigationBarClass
toolbarClass:(Class)toolbarClass;
现在,当导航 controller 被实例化时,您只需传递您的自定义 class。
从 iOS6 开始,使用UINavigationControllers
方法initWithNavigationBarClass:toolbarClass:
- (id)initWithNavigationBarClass:(Class)navigationBarClass
toolbarClass:(Class)toolbarClass;
从文档:
初始化并返回使用您的自定义栏子类的新创建的导航 controller。
为 iOS6 更新了答案。
iOS 4 中唯一支持的方法是使用 Interface Builder 方法。 除了设置 UINavigationBar 子类(您仍然可以以编程方式设置所有视图)之外,您不必使用 IB 来做任何事情。
- (id)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass;
我在上述方法中遇到了一个问题。 有一个“initWithRootViewController”方法来初始化 UINavigationController。 但是,如果我使用“initWithNavigationBarClass”来初始化 UINavigationController,那么我无法为 UINavigationController 设置“rootViewController”。
此链接更改 UINavigationController 的 rootViewController帮助我在使用“initWithNavigationBarClass”初始化 UINavigationController 后添加了 rootViewController。 基本上,诀窍是继承 UINavigationController。 虽然我还没有在 IB 中测试过它,但它在代码中运行良好。
对于那些仍然想使用initWithRootViewController
的人来说,对上述答案的一种修正。 子类UINavigationController
然后:
- (id) initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithNavigationBarClass:[CustomNavigationBar class] toolbarClass:nil];
if (self)
{
self.viewControllers = [NSArray arrayWithObjects:rootViewController, nil];
}
return self;
}
iOS 4 中的答案 2-4 有问题(来自 AnswerBot 的答案),并且需要一种以编程方式加载 UINavigationController 的方法(尽管 NIB 方法有效)......所以我这样做了:
Created a Blank XIB file (don't set file owner), add a UINavigationController (give it your custom UINavigationController's class), change the UINavigationBar to your custom class (here it's CustomNavigationBar), then create the following custom class header (CustomNavigationController.h在这种情况下):
#import <UIKit/UIKit.h>
@interface CustomNavigationController : UINavigationController
+ (CustomNavigationController *)navigationController;
+ (CustomNavigationController *)navigationControllerWithRootViewController:(UIViewController *)rootViewController;
@end
和自定义实现(CustomNavigationController.mm)
#import "CustomNavigationController.h"
@interface CustomNavigationController ()
@end
@implementation CustomNavigationController
+ (CustomNavigationController *)navigationController
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomNavigationController" owner:self options:nil];
CustomNavigationController *controller = (CustomNavigationController *)[nib objectAtIndex:0];
return controller;
}
+ (CustomNavigationController *)navigationControllerWithRootViewController:(UIViewController *)rootViewController
{
CustomNavigationController *controller = [CustomNavigationController navigationController];
[controller setViewControllers:[NSArray arrayWithObject:rootViewController]];
return controller;
}
- (id)init
{
self = [super init];
[self autorelease]; // We are ditching the one they allocated. Need to load from NIB.
return [[CustomNavigationController navigationController] retain]; // Over-retain, this should be alloced
}
- (id)initWithRootViewController:(UIViewController *)rootViewController
{
self = [super init];
[self autorelease];
return [[CustomNavigationController navigationControllerWithRootViewController:rootViewController] retain];
}
@end
然后您可以只初始化 class 而不是 UINavigationController,您将拥有自定义导航栏。 如果您想在 xib 中执行此操作,请在您的 XIB 中更改 UINavigationController 和 UINavigationBar 的 class 和 UINavigationBar。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.