Objective c UINavigationBar顶部项目/项目背面似乎双重弹出

Objective c UINavigationBar顶部项目/项目背面似乎双重弹出,objective-c,cocoa-touch,uikit,uinavigationbar,Objective C,Cocoa Touch,Uikit,Uinavigationbar,我正在管理我自己的UINavigationBar。我需要这样做,因为广泛的皮肤。UINavigationController的文档警告,当与UINavigationController一起使用时,对UINavigationBar进行蒙皮有一些限制 我已经做了大量的日志记录,从我所知道的一切来看,按下UINavigationController中的“后退”按钮会从堆栈中弹出两个项目,而不是一个。我收到一个委托回调,告诉我它正在删除逻辑项,但实际上它删除了一个又一个逻辑项 决不应删除在awakeFr

我正在管理我自己的UINavigationBar。我需要这样做,因为广泛的皮肤。UINavigationController的文档警告,当与UINavigationController一起使用时,对UINavigationBar进行蒙皮有一些限制

我已经做了大量的日志记录,从我所知道的一切来看,按下UINavigationController中的“后退”按钮会从堆栈中弹出两个项目,而不是一个。我收到一个委托回调,告诉我它正在删除逻辑项,但实际上它删除了一个又一个逻辑项

决不应删除在awakeFromNib中添加到UINavigationController的项。由于某种原因,它正在被删除

有两个类似的问题,但都没有令人满意的答案。这两个问题是:

编辑以从单个运行添加相关调试:

2010-10-13 02:12:45.911 Remix2[17037:207] didPushItem: <TableDisplay: 0x5d41cc0>
2010-10-13 02:12:45.912 Remix2[17037:207] Current items: (
    "<TableDisplay: 0x5d41cc0>"
)
2010-10-13 02:12:49.020 Remix2[17037:207] didPushItem: <WebDisplay: 0x591a590>
2010-10-13 02:12:49.021 Remix2[17037:207] Current items: (
    "<TableDisplay: 0x5d41cc0>",
    "<WebDisplay: 0x591a590>"
)
2010-10-13 02:12:49.023 Remix2[17037:207] Selected story: <WebDisplay: 0x591a590>
2010-10-13 02:12:59.498 Remix2[17037:207] didPopItem: <WebDisplay: 0x591a590>
2010-10-13 02:12:59.499 Remix2[17037:207] Current items: (
)
2010-10-13 02:12:45.911 Remix2[17037:207]项目:
2010-10-13 02:12:45.912[17037:207]当前项目:(
""
)
2010-10-13 02:12:49.020 Remix2[17037:207]
2010-10-13 02:12:49.021 Remix2[17037:207]当前项目:(
"",
""
)
2010-10-13 02:12:49.023 Remix2[17037:207]精选故事:
2010-10-13 02:12:59.498 Remix2[17037:207]didPopItem:
2010-10-13 02:12:59.499 Remix2[17037:207]当前项目:(
)

根据
-awakeFromNib
的文档,当子类实现该方法时,始终必须调用
[super awakeFromNib]

您必须调用awakeFromNib的超级实现,以使父类有机会执行它们所需的任何附加初始化

然而,重要的是

我不明白你为什么要管理自己的导航栏。如果您将
UINavigationBar
子类化,并且只覆盖某些绘图或布局方法,例如
-drawRect:
-layoutSubviews
等,那么在导航控制器中管理导航栏的所有逻辑都将回到原来的
UINavigationBar

我必须对几乎每个主要的
UIKit
类进行广泛的视图定制,但我总是将复杂的逻辑留给原始类,只覆盖绘图方法来定制外观

顺便说一句,如果您所做的只是使用自定义的图像资源,那么在不进行子类化的情况下对整个应用程序进行蒙皮实际上要容易得多。通过设置图层的
内容
属性,您可以根据需要或在整个应用程序中自定义基于
UIView
的类的外观:

#import <QuartzCore/QuartzCore.h>
...
- (void)viewDidLoad
{
    [super viewDidLoad];

    UIImage * navigationBarContents = [UIImage imageNamed:@"navigation-bar"];
    self.navigationController.navigationBar.layer.contents =    
        (id)navigationBarContents.CGImage;
}
#导入
...
-(无效)viewDidLoad
{
[超级视图下载];
UIImage*navigationBarContents=[UIImage ImageName:@“导航栏”];
self.navigationController.navigationBar.layer.contents=
(id)navigationBarContents.CGImage;
}

您可以为从
UIView
继承的任何类设置内容:导航栏、工具栏、按钮等。这样管理起来就容易多了,根本不需要子类。

这似乎是
-[UINavigationBar项]实现中的一个错误。

当从
-navigationBar:didPopItem:
委托方法内部调用时,它将忽略最后一个对象。您可以通过调用
[navigationBar valueForKey:@“\u itemStack”]
检索基础数组并查看所需的项是否仍然存在来检查这一点


-navigationBar:didPopItem:
内部添加
dispatch\u async
方法成功地解决了我的应用程序中的问题。

来自UINavigationBar文档:当与导航控制器结合使用时,您只能对导航栏进行少量直接自定义。具体来说,可以修改此类的barStyle、tintColor和半透明属性,但决不能直接更改UIView级别的属性,如框架、边界、alpha或隐藏属性。此外,您应该让导航控制器管理导航项目的堆栈,而不是自己尝试修改这些项目。在这方面,修改视图层的
内容
属性完全可以。相信我,我已经使用了我在上面发布的技术,在一些情况下只修改了我的导航栏的外观,留下了它们的所有其他特征:按钮、按下/弹出、标题等等,这正是为所有
UIView
对象提供支持
CALayer
的目的。我有完全相同的问题,但我让导航控制器处理我的自定义蒙皮导航栏。你找到答案了吗?
#import <QuartzCore/QuartzCore.h>
...
- (void)viewDidLoad
{
    [super viewDidLoad];

    UIImage * navigationBarContents = [UIImage imageNamed:@"navigation-bar"];
    self.navigationController.navigationBar.layer.contents =    
        (id)navigationBarContents.CGImage;
}