几个小时后,我想我已经找到了一个解决方法。我发现了这个解决方案,因为我有一些有趣的行为可以切换可以工作的按钮颜色,但是直接在 viewDid/Will/whatever 中设置按钮颜色是行不通的。不同之处似乎是必须在调用 viewDidLoad 之后的某个时间在 navigationItem 上创建和设置按钮。
长话短说,在下面的 UINavigationControllerDelegate 方法中重新创建按钮、设置按钮色调和更新 navigationItem 就成功了:
- (void) navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
为了使这对我的应用程序尽可能透明,我使用了以下委托,它将在视图控制器中查找方法并在正确的时间调用它:
iOS7ButtonTintWorkAround.h:
@interface RMSiOS7ButtonTintWorkAround : NSObject <UINavigationControllerDelegate>
@property (nonatomic, strong) RMSiOS7ButtonTintWorkAround* preventGC;
- (id)initWithNavigationController:(UINavigationController*)navigationController;
@end
iOS7ButtonTintWorkAround.m:
#import "iOS7ButtonTintWorkAround.h"
@implementation iOS7ButtonTintWorkAround
NSObject<UINavigationControllerDelegate>* _delegate;
- (id)initWithNavigationController:(UINavigationController*)navigationController
{
self = [super init];
if (self) {
_delegate = [navigationController delegate];
[navigationController setDelegate:self];
_preventGC = self;
}
return self;
}
- (void) navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if(_delegate) {
[_delegate navigationController:navigationController willShowViewController:viewController animated:animated];
}
}
- (void) navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if(_delegate) {
[_delegate navigationController:navigationController willShowViewController:viewController animated:animated];
}
if([viewController respondsToSelector:@selector(iOS7SetBarButtonTint)]) {
[viewController performSelector:@selector(iOS7SetBarButtonTint)];
}
}
@end
因为委托属性不是强引用,所以有必要做一些事情来防止委托被 GC'd。我没有创建那么多 UINavigationController,所以我可以忍受泄漏,但是如果有人可以建议一种方法来让委托保持活动,只要它的 UINavigationController,我有兴趣知道吗?