问题描述
我正在尝试在正常和突出显示状态下设置后退按钮的背景图像。
I am trying to set the background image for back button in normal and highlighted states.
- (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>
但突出显示状态的观察结果只是设置为正常状态而不是使用正确突出显示图像。
But observed result for highlighted state is just dimming of what was set to the normal state instead of using the correct highlighted image.
正常:
突出显示(箭头仍然是白色,按钮意外变暗):
Highlighted (Arrow is still white, button is dimmed unexpectedly):
请不要将有关leftBarButtonItem或UIButton用法的答案发布为自定义视图。这两种方法都可以在iOS 7上实现刷卡到后退行为。
Please do not post answers regarding usage of leftBarButtonItem or UIButton as custom view. Both these approaches brake swipe-to-go-back behavior available on iOS 7.
UPD:关于此问题的已填充雷达#17481106。
UPD: filled radar #17481106 regarding this issue.
UPD2:雷达#17481106已在iOS 8中修复。
UPD2: radar #17481106 fixed in iOS 8.
推荐答案
目前Apple在<$ c上有错误$ c> interactivePopGestureRecognizer (这会在刷推推动画片后冻结导航控制器的视图,你会看到嵌套的流行动画可能导致导航栏损坏
Currently Apple has bug on interactivePopGestureRecognizer
(which makes to freeze navigation controller's view after swiping back on push animation, you will see nested pop animation can result in corrupted navigation bar
warning in console), by the way, we can make a small hack to work around that bug.
这是一个对我来说很好的解决方案,
Here is a solution that works fine for me,
对一个NavigationController类进行子类化并使其委派手势
@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
当用户开始向后滑动时在转换过程中,pop事件会叠加并破坏导航堆栈。我的解决方法是在推送转换期间暂时禁用手势识别器,并在新视图控制器加载时再次启用它。同样,使用UINavigationController子类更容易。
When the user starts swiping backwards in the middle of a transition, the pop events stack up and "corrupt" the navigation stack. My workaround is to temporarily disable the gesture recognizer during push transitions, and enable it again when the new view controller loads. Again, this is easier with a UINavigationController subclass.
在此之后,您可以平静地使用 item.leftBarButtonItem
和 UIButton
作为自定义视图。
After this, you can calmly use item.leftBarButtonItem
and UIButton
as custom view.
这篇关于iOS 7:如何为UIControlStateHighlighted设置UIBarButtonItem backButtonBackgroundImage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!