2009-08-14 55 views
2

我手动管理我的视图的UINavigationBar。 Bar本身和第一个UINavigationItem是在Interface Builder中创建的。在我的代码中,基于各种事件,我将新的导航项目推送到栏上,并将适当的视图作为主视图的子视图进行绘制。这一切似乎都很好,但是当我选择导航栏后退按钮时,两件物品会从物品堆栈中删除,而不是像我所预期的那样。为了测试,我把我的控制器为代表的酒吧和陷阱2委托方法:UINavigationBar似乎弹出2个项目在“后退”堆栈

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

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

我弹出前右发现,在导航栏的项目是正确的,例如,3.在第二种方法中,在弹出之后,即使弹出的项目是最后一个项目,项目也是1 - 不知何故中间项目丢失。我很难理解如何调试,并会欣赏任何想法。

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

回答

0

“我正在为我的视图手动管理一个 UINavigationBar。”

不这样做。 ;-)

说真的。我想不出有一个很好的理由来管理它,如果你不是很小心,你会遇到的问题,使整个应用程序无法管理。那么为什么不在你的根视图中创建一个连接到你的XIB的UINavigationController呢?你想通过自己管理导航栏来克服什么问题?

至于你遇到的问题 - 你得到两个流行音乐,因为你正在做的事情在shouldPopItem,告诉它再次弹出。这是试图自己管理导航栏的效果。请记住,shouldPopItem和didPopItem只与导航栏相关,而不与导航控制器和视图相关。当你用[[self navigationController] popViewControllerAnimated:YES]弹出视图控制器;它会调用shouldPopItem。既然你压倒一切,你必须管理一切。

+0

是的,谢谢。我在想,也许有人调用didPopItem和shouldPopItem两次,这就是为什么我设置了委托方法,以便可以捕获这些方法。他们只被调用一次。 当时看起来更容易扩展我的viewcontroller而不是实现导航控制器。考虑到IB给你提供的工具来设置它,我认为它是可以的。另外,我对iphone开发相当陌生,并且喜欢理解框架机制。我已经在我的工作方式现在,并粉笔这与环境,以避免我的理解又一件事... – farhadf 2009-08-17 17:21:52

0

我会放置一个NSLog()声明在您shouldPopItemdidPopItem方法从头开始 - 这会给你的他们多少次获取调用,当一个想法。接下来,您可以在应用程序中的各个位置记录视图控制器堆栈的大小,以便您可以观察它的增长和缩小。如果这两者都不起作用,只需手动开始放置断点并检查堆栈跟踪/查看控制器堆栈大小即可。

+0

谢谢 - 我在我的帖子不是很干净 - 这正是我正在做的 - 设置断点并查看堆栈的大小以及堆栈上的内容。很奇怪。 – farhadf 2009-08-17 17:20:16

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:方法。然后使用该子类代替标准UINavigationControllerUINavigationBar,并且所有内容都将按照正常情况运行,只能使用自定义样式的导航栏。

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