Duc*_*cio 92 objective-c uinavigationbar uinavigationcontroller
UINavigationBar
如果我以UINavigationController
编程方式实例化(没有IB),有谁知道如何使用我的自定义子类?
拖动UINavigationController
在IB中显示我在导航栏下并使用Identity Inspectory我可以更改类类型并设置我自己的子类UINavigationBar
但编程方式我不能,navigationBar
导航控制器的属性是只读...
我该怎么做才能以编程方式自定义导航栏?IB比"代码"更"强大"吗?我相信在IB中可以做的所有事情也可以通过编程方式完成.
小智 89
只需使用KVC,您就不需要使用XIB.
[self.navigationController setValue:[[[CustomNavBar alloc]init] autorelease] forKeyPath:@"navigationBar"];
Run Code Online (Sandbox Code Playgroud)
Pas*_*ius 66
从iOS5开始,apple提供了一种直接执行此操作的方法.参考
UINavigationController *navigationController= [[UINavigationController alloc]initWithNavigationBarClass:[CustomNavBar class] toolbarClass:nil];
[navigationController setViewControllers:[NSArray arrayWithObject:yourRootViewController]];
Run Code Online (Sandbox Code Playgroud)
小智 37
从iOS 4开始,您可以使用UINib
该类来帮助解决此问题.
UINavigationBar
子类.UINavigationController
作为单个对象.UINavigationController
s 的类设置为UINavigationBar
自定义子类.[navController setViewcontrollers[NSArray arrayWithObject:myRootVC]];
[navController pushViewController:myRootVC];
在代码中:
UINib *nib = [UINib nibWithNibName:@"YourCustomXib" bundle:nil];
UINavigationController *navController =
[[nib instantiateWithOwner:nil options:nil] objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)
现在你有了UINavigationController
自定义UINavigationBar
.
Mic*_*son 26
据我所知,有时确实有必要对UINavigationBar进行子类化,以进行一些非标准的重新定位.有时可以通过使用类别来避免这样做,但并非总是如此.
目前,据我所知,在UIViewController中设置自定义UINavigationBar 的唯一方法是通过IB(即通过存档) - 它可能不应该那样,但是现在,我们必须接受它.
这通常很好,但有时使用IB并不可行.
所以,我看到了三个选择:
在这种情况下,选项1对我来说是不可行的(或者至少太烦人),因为我需要以编程方式创建UINavigationController,2在我看来有点危险并且更多是最后的选择,所以我选择了选项3.
我的方法是创建一个UINavigationController的"模板"存档,并将其归档,将其返回initWithRootViewController
.
这是如何做:
在IB中,我创建了一个UINavigationController,其中包含适用于UINavigationBar的类集.
然后,我使用现有的控制器,并使用保存了它的存档副本+[NSKeyedArchiver archiveRootObject:toFile:]
.我只是在app委托中,在模拟器中完成了这个.
然后我使用'xxd'实用程序和-i标志,从保存的文件生成c代码,将存档版本嵌入到我的子类(xxd -i path/to/file
)中.
在initWithRootViewController
我取消归档该模板,并将self设置为unarchive的结果:
// This is the data from [NSKeyedArchiver archivedDataWithRootObject:controller], where
// controller is a CTNavigationController with navigation bar class set to CTNavigationBar,
// from IB. This c code was created using 'xxd -i'
static unsigned char archived_controller[] = {
0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd4, 0x01, 0x02, 0x03,
...
};
static unsigned int archived_controller_len = 682;
...
- (id)initWithRootViewController:(UIViewController *)rootViewController {
// Replace with unarchived view controller, necessary for the custom navigation bar
[self release];
self = (CTNavigationController*)[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithBytes:archived_controller length:archived_controller_len]];
[self setViewControllers:[NSArray arrayWithObject:rootViewController]];
return [self retain];
}
Run Code Online (Sandbox Code Playgroud)
然后,我可以抓住我的UIViewController子类的一个新实例,它具有自定义导航栏集:
UIViewController *modalViewController = [[[CTNavigationController alloc] initWithRootViewController:myTableViewController] autorelease];
[self.navigationController presentModalViewController:modalViewController animated:YES];
Run Code Online (Sandbox Code Playgroud)
这给了我一个模态UITableViewController,其中包含一个导航栏和工具栏,并且具有自定义导航栏类.我不需要做任何稍微讨厌的方法替换,当我真的只想以编程方式工作时,我不必捣乱nib.
我想+layerClass
在UINavigationController中看到相同的东西+navigationBarClass
- 但是现在,这是有效的.
小智 5
我用"选项1"
创建一个只包含UINavigationController的nib文件.并将UINavigationBar类设置为我的自定义类.
self.navigationController = [[[NSBundle mainBundle] loadNibNamed:@"navigationbar" owner:self options:nil] lastObject];
[navigationController pushViewController:rootViewController animated:YES];
Run Code Online (Sandbox Code Playgroud)
Michael的解决方案有效,但您可以避免使用NSKeyedArchiver和'xxd'实用程序.只需子类UINavigationController并覆盖initWithRootViewController
,直接加载您的自定义NavigationController NIB:
- (id) initWithRootViewController:(UIViewController *)rootViewController
{
[self release];
self = [[[[NSBundle mainBundle] loadNibNamed:@"CTNavigationController" owner:nil options:nil] objectAtIndex:0] retain];
[self setViewControllers:[NSArray arrayWithObject:rootViewController]];
return self;
}
Run Code Online (Sandbox Code Playgroud)
不建议对UINavigationBar
类进行子类化。自定义导航栏的首选方法是设置其属性以使其按您的意愿显示,并使用 UIBarButtonItems 内的自定义视图以及委托来获得所需的行为。
您想要做什么需要子类化?
另外,我不认为 IB 实际上正在取代导航栏。我很确定它只是不显示默认导航栏,而是将您的自定义导航栏作为子视图。如果您调用 UINavigationController.navigationBar,您会获得导航栏的实例吗?