1

UINavigationItem具有以下私有变量

UIKIT_EXTERN_CLASS @interface UINavigationItem : NSObject <NSCoding> {

@private
 NSString        *_title;
 NSString        *_backButtonTitle;
 UIBarButtonItem *_backBarButtonItem;
 NSString        *_prompt;
 NSInteger        _tag;
 id               _context;
 UINavigationBar *_navigationBar;
 UIView          *_defaultTitleView;
 UIView          *_titleView;
 UIView          *_backButtonView;
 UIBarButtonItem *_leftBarButtonItem;
 UIBarButtonItem *_rightBarButtonItem;
 UIView          *_customLeftView;
 UIView          *_customRightView;
 BOOL             _hidesBackButton;
 UIImageView     *_frozenTitleView;

}

有什么方法(使用 KVC 等)来读取UINavigationBar *_navigationBar; 我需要这个来访问未定义的 backButton。这不在:

@property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem; @property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;

4

3 回答 3

4

不要这样做。它违反了封装的基本 OOP 概念。如果 Apple 决定重新排列类中 ivars 的顺序或含义UINavigationItem,您的代码可能会意外中断,包括崩溃或吃人的紫龙。


也就是说,如果您确定要走这条邪恶的 邪恶之路,您应该能够通过以下方式到达_navigationBarivar:

UINavigationItem *theItem = ...;
UINavigationBar *bar = [theItem valueForKey: @"_navigationBar"];

如果这不起作用(例如,如果 Apple 已覆盖+accessInstanceVariablesDirectly此类),您可以下拉到 Objective-C 运行时:

#include <objc/runtime.h>

UINavigationItem *theItem = ...;
UINavigationBar *bar = nil;
Ivar barIvar = class_getInstanceVariable([UINavigationItem class], "_navigationItem");
if (barIvar) {
    bar = *(UINavigationBar *)((void *)theItem + ivar_getOffset(barIvar));
}

这两种方法都非常危险,并且有可能破坏操作系统的任何一个版本。你被警告了。这里是龙。

于 2012-06-01T20:18:29.073 回答
0

您需要访问 UINavigationController 上的导航栏,而不是 UINavigationItem

于 2012-06-01T20:09:24.747 回答
0

理想情况下,您会像 Christian 所说的那样访问 UINavigationController 上的导航栏。

如果必须通过 UINavigationItem 访问 navigationBar,创建 UINavigationItem 的自定义子类,那么自定义变量是一种替代方法。

最后,如果您真的不太关心任何替代方案并且真的非常想访问该属性,那么您只需调用:

[myNavigationItem performSelector:@selector(navigationBar)]

当然,通常的“会让你的应用程序被拒绝”或“这不是好的编码”语句适用。

于 2012-06-01T20:17:53.547 回答