UINavigationBar似乎在“背面”弹出2个项目

时间:2009-08-14 22:54:53

标签: iphone cocoa-touch

我正在为我的视图手动管理UINavigationBar。 Bar本身和第一个UINavigationItem是在Interface Builder中创建的。在我的代码中,基于各种事件,我将新的导航项目推送到条形图上,并将相应的视图绘制为主视图的子视图。这一切看起来都很好,但是当我选择导航栏后退按钮时,两个项目会从项目堆栈中删除,而不是像我预期的那样。为了测试,我将控制器设置为条形图的委托并捕获2个委托方法:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; 

- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;

我在pop之前发现,导航栏中的项目是正确的,例如,3。在第二种方法中,就在pop之后,项目为1,即使弹出的项目是最后一项 - 不知何故缺少中间项目。我很难过如何调试这个并且会感激任何想法。

请注意,由于各种原因,我没有使用导航控制器。

5 个答案:

答案 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;
}