我正在为我的视图手动管理UINavigationBar。 Bar本身和第一个UINavigationItem是在Interface Builder中创建的。在我的代码中,基于各种事件,我将新的导航项目推送到条形图上,并将相应的视图绘制为主视图的子视图。这一切看起来都很好,但是当我选择导航栏后退按钮时,两个项目会从项目堆栈中删除,而不是像我预期的那样。为了测试,我将控制器设置为条形图的委托并捕获2个委托方法:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
和
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;
我在pop之前发现,导航栏中的项目是正确的,例如,3。在第二种方法中,就在pop之后,项目为1,即使弹出的项目是最后一项 - 不知何故缺少中间项目。我很难过如何调试这个并且会感激任何想法。
请注意,由于各种原因,我没有使用导航控制器。
答案 0 :(得分:0)
“我正在手动管理一个 我的观点是UINavigationBar。“
不要那样做。 ; - )
严重。我想不出自己管理它的好理由,如果你不是很小心,你会遇到使整个应用程序无法管理的问题。那么为什么不在根视图中创建一个连接到XIB的UINavigationController呢?你想通过管理导航栏来克服什么问题?
至于你遇到的问题 - 你得到两个pops,因为你在shouldPopItem中做了一些事情,告诉它再次弹出。这是尝试自己管理导航栏的效果。请记住,shouldPopItem和didPopItem仅与导航栏有关,而与导航控制器和视图无关。使用[[self navigationController] popViewControllerAnimated:YES]弹出视图控制器时;它将调用shouldPopItem。既然你是最重要的,你必须管理一切。
答案 1 :(得分:0)
我首先在NSLog()
和shouldPopItem
方法的开头添加didPopItem
语句 - 这样可以让您知道他们被调用的次数,以及什么时候。接下来,您可以在整个应用程序的不同位置记录视图控制器堆栈的大小,以便您可以观察它的增长和缩小。如果这些都不起作用,只需开始放置断点并手动检查堆栈跟踪/查看控制器堆栈大小。
答案 2 :(得分:0)
替换或排除UINavigationController
等核心类几乎从来都不可接受。相信我,我见过有人这么做了,应用程序充满了问题 - 我不得不处理它们。请看一下UINavigationController.h
。它管理着大量的州等等。你为什么要管理自己的导航栏?
相反,像UINavigationBar
这样的“轻微”子类可以覆盖某些绘图/布局方法。这样做可以让所有复杂的逻辑按预期回归到基类。
更好的是,只需使用导航栏的contents
属性,如果您要做的就是使用自定义图像设置样式:
#import <QuartzCore/QuartzCore.h>
...
- (void)viewDidLoad
{
UIImage * navigationBarContents = [UIImage imageNamed:@"navigation-bar"];
self.navigationController.navigationBar.layer.contents =
(id)navigationBarContents.CGImage;
}
您可以对任何UIView
子类执行此操作,以便轻松,干净地更改其使用图像的外观。当然,如果您正在进行自定义绘图,只需子类UINavigationBar
并仅覆盖-drawRect:
方法。然后使用该子类代替带有标准UINavigationBar
的{{1}},并且所有内容都将按照通常的方式运行,仅使用自定义样式的导航栏。
答案 3 :(得分:0)
我不知道为什么UINavigationBar表现得像这样,但我有一个棘手的解决方案。
- (BOOL)navigationBar:(UINavigationBar *)navigationBar
shouldPopItem:(UINavigationItem *)item
{
NSMutableArray *items = navigationBar.items.mutableCopy;
[items removeObject:item];
// Now var 'items' contains the proper instances of UINavigationItem. To be exact, one more than the instances in 'navigationBar.items'.
return YES;
}
答案 4 :(得分:0)
检查poppage是用户启动的还是程序化的,如此
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
UIViewController *topViewController = self.topViewController;
... some logic that justifies implementing shouldPopItem: delegate in the first place -> others have explained the caveats so I won't repeat that ...
// manual as in opposite of programmatic
BOOL manualPop = topViewController.navigationItem == item;
if(manualPop) {
[self popViewControllerAnimated:YES];
}
return YES;
}