如何以编程方式为UINavigationControllerinheritanceUINavigationBar?

我使用一个自定义的drawRect函数在iOS4中的应用程序上绘制UINavigationBar ,它不使用图像,只使用CoreGraphics。

既然你不能在iOS5的UINavigationBar类中实现drawRect,Applebuild议子类UINavigationBar

navigationBar属性是只读的时,如何用UINavigationBar子类replaceUINavigationController (所以它将与iOS4和iOS5兼容)?

 @property(nonatomic, readonly) UINavigationBar *navigationBar 

我没有在应用程序中使用XIB,所以将UINavigationBar添加到NIB并通过InterfaceBuilder更改类不是一个选项。

从iOS6开始,现在使用UINavigationControllers方法initWithNavigationBarClass:toolbarClass:方法可以很容易地完成,而不会与其他类混淆或混淆initWithNavigationBarClass:toolbarClass:

 - (id)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass; 

从文档:

初始化并返回一个新创build的使用自定义栏子类的导航控制器。

为iOS6更新了答案。

在iOS 6中,他们为UINavigationController添加了一个新的方法,这个方法也可以在iOS 5中UINavigationController使用:

 - (id)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass; 

现在,您可以在实例化导航控制器时传递您的自定义类。

在iOS 4中唯一受支持的方法是使用Interface Builder方法。 除了设置UINavigationBar子类之外,您不必使用IB来执行任何操作(您仍然可以以编程方式设置所有视图)。

 - (id)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass; 

我遇到了上述方法的一个问题。 有一个“initWithRootViewController”方法来初始化UINavigationController。 但是,如果我使用“initWithNavigationBarClass”来初始化UINavigationController,那么我无法为UINavigationController设置“rootViewController”。

这个链接改变一个UINavigationController的rootViewController帮助我添加一个rootViewController后,用“initWithNavigationBarClass”初始化UINavigationController。 基本上,诀窍是子类UINavigationController。 虽然我还没有在IBtesting过它,但它在代码中工作正常。

在iOS 4(从AnswerBot的答案)有答案2-4的问题,并需要一种方式来加载UINavigationController以编程方式(虽然NIB方法工作)…所以我这样做:

创build一个空白的XIB文件(不要设置文件所有者),添加一个UINavigationController(给它你自定义的UINavigationController的类),将UINavigationBar更改为你的自定义类(这里是CustomNavigationBar),然后创build下面的自定义类头(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 

然后,您可以只启动该类而不是UINavigationController,并且您将拥有自定义导航栏。 如果您想在xib中执行此操作,请更改XIB中的UINavigationController和UINavigationBar类。

对于那些仍然想要使用initWithRootViewController上述答案的修正。 子类UINavigationController然后:

 - (id) initWithRootViewController:(UIViewController *)rootViewController { self = [super initWithNavigationBarClass:[CustomNavigationBar class] toolbarClass:nil]; if (self) { self.viewControllers = [NSArray arrayWithObjects:rootViewController, nil]; } return self; }