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