Как создать подкласс UINavigationBar для UINavigationController программно?
Я использую пользовательскую функцию drawRect, чтобы рисовать на UINavigationBar
в моем приложении в iOS4 оно не использует изображения, только CoreGraphics.
Поскольку вы не можете реализовать drawRect в UINavigationBar
Apple в категории iOS5 предлагает подкласс UINavigationBar
,
Как можно заменить UINavigationBar
с моим подклассом в UINavigationController
(так что он будет совместим с iOS4 и iOS5), когда navigationBar
свойство только для чтения?
@property(nonatomic, readonly) UINavigationBar *navigationBar
Я вообще не использую XIB в своем приложении, поэтому добавляю UINavigationBar
к NIB и изменение класса через InterfaceBuilder не вариант.
6 ответов
Начиная с iOS6, теперь это довольно просто сделать без использования других классов с помощью UINavigationControllers
метод initWithNavigationBarClass:toolbarClass:
- (id)initWithNavigationBarClass:(Class)navigationBarClass
toolbarClass:(Class)toolbarClass;
Из документов:
Инициализирует и возвращает вновь созданный контроллер навигации, который использует ваши пользовательские подклассы панели.
Ответ обновлен для iOS6.
В iOS 6 они добавили новый метод UINavigationController
это доступно и в iOS 5:
- (id)initWithNavigationBarClass:(Class)navigationBarClass
toolbarClass:(Class)toolbarClass;
Теперь вы можете просто передать свой пользовательский класс при создании экземпляра контроллера навигации.
Единственный поддерживаемый способ сделать это в iOS 4 - использовать метод Interface Builder. Вам не нужно использовать IB, чтобы делать что-либо, кроме как установить подкласс UINavigationBar (вы все равно можете сделать все свои представления настроенными программно).
Вид поправки к ответам выше для тех, кто все еще хочет использовать initWithRootViewController
, Подкласс UINavigationController
а потом:
- (id) initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithNavigationBarClass:[CustomNavigationBar class] toolbarClass:nil];
if (self)
{
self.viewControllers = [NSArray arrayWithObjects:rootViewController, nil];
}
return self;
}
- (id)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass;
Я столкнулся с одной проблемой, описанной выше. Для инициализации UINavigationController существует метод initWithRootViewController. Но если я использую "initWithNavigationBarClass" для инициализации UINavigationController, то я не смогу установить "rootViewController" для UINavigationController.
Эта ссылка Изменение rootViewController в UINavigationController помогло мне добавить rootViewController после того, как UINavigationController инициализирован с помощью initWithNavigationBarClass. По сути, дело в том, чтобы создать подкласс UINavigationController. Хотя я еще не тестировал его в IB, но в коде он работает нормально.
У него были проблемы с ответами 2-4 в iOS 4 (из ответа AnswerBot), и нужен был способ загрузить UINavigationController программно (хотя метод NIB работал)... Итак, я сделал это:
Создайте пустой XIB-файл (не устанавливайте владельца файла), добавьте UINavigationController (предоставьте ему свой пользовательский класс UINavigationController), измените UINavigationBar на свой пользовательский класс (здесь это CustomNavigationBar), затем создайте следующий заголовок пользовательского класса (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, измените класс UINavigationController и UINavigationBar внутри вашей XIB.