我正在尝试为正常和突出显示状态下的后退按钮设置背景图像。
- (void)configureBackButtonInNavigationItem:(UINavigationItem *)item
{
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"back"
style:UIBarButtonItemStyleBordered target:nil action:NULL];
[backBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]} forState:UIControlStateNormal];
[backBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor orangeColor]} forState:UIControlStateHighlighted];
// white arrow image
UIImage *normalImage = [[[UIImage imageNamed:@"btn_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] resizableImageWithCapInsets:UIEdgeInsetsMake(0.f, 17.f, 0.f, 0.f)];
// orange arrow image
UIImage *pressedImage = [[[UIImage imageNamed:@"btn_on_press"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] resizableImageWithCapInsets:UIEdgeInsetsMake(0.f, 17.f, 0.f, 0.f)];
[backBarButtonItem setBackButtonBackgroundImage:normalImage
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[backBarButtonItem setBackButtonBackgroundImage:pressedImage
forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
[backBarButtonItem setBackgroundImage:normalImage
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[backBarButtonItem setBackgroundImage:pressedImage
forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
NSLog(@"NORMAL: %@ HIGHLIGHTED: %@", [backBarButtonItem backButtonBackgroundImageForState:UIControlStateNormal barMetrics:UIBarMetricsDefault],
[backBarButtonItem backButtonBackgroundImageForState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]);
item.backBarButtonItem = backBarButtonItem;
NSLog(@"NORMAL: %@ HIGHLIGHTED: %@", [backBarButtonItem backButtonBackgroundImageForState:UIControlStateNormal barMetrics:UIBarMetricsDefault],
[backBarButtonItem backButtonBackgroundImageForState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]);
}
输出如下:
NORMAL: <_UIResizableImage: 0x16b55e10> HIGHLIGHTED: <_UIResizableImage: 0x16b593d0>
NORMAL: <_UIResizableImage: 0x16b55e10> HIGHLIGHTED: <_UIResizableImage: 0x16b593d0>
但高亮状态的观察结果只是将设置为正常状态的内容变暗,而不是使用正确的高亮图像。
正常:
突出显示(箭头仍然是白色,按钮意外变暗):
请不要发布有关使用 leftBarButtonItem 或 UIButton 作为自定义 View 的答案。这两种方法都破坏了 iOS 7 上可用的滑动返回行为。
UPD:关于此问题的填充雷达#17481106。
UPD2:雷达 #17481106 已在 iOS 8 中修复。
最佳答案
目前 Apple 在 interactivePopGestureRecognizer 上有错误(这使得在推送动画上向后滑动后卡住导航 Controller 的 View ,你会看到嵌套的弹出动画会导致导航栏损坏控制台中的警告),顺便说一下,我们可以做一些小改动来解决这个错误。
这是一个适合我的解决方案,
子类化 NavigationController 类并使其委托(delegate)手势
@interface CBNavigationController : UINavigationController
@end
@implementation CBNavigationController
- (void)viewDidLoad
{
__weak CBNavigationController *weakSelf = self;
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
}
// Hijack the push method to disable the gesture
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = NO;
[super pushViewController:viewController animated:animated];
}
#pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animate
{
// Enable the gesture again once the new controller is shown
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = YES;
}
@end
当用户在转换过程中开始向后滑动时,弹出事件会堆叠起来并“破坏”导航堆栈。我的解决方法是在推送转换期间暂时禁用手势识别器,并在新 View Controller 加载时再次启用它。同样,使用 UINavigationController 子类会更容易。
在此之后,您可以从容地使用item.leftBarButtonItem 和UIButton 作为自定义 View 。
关于iOS 7 : How to set UIBarButtonItem backButtonBackgroundImage for UIControlStateHighlighted?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23665841/