iOS 7:如何为 UIControlStateHighlighted 设置 UIBarButtonItem backButtonBackgroundImage?

2024-04-04

我正在尝试在正常和突出显示状态下设置后退按钮的背景图像。

- (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>

但是突出显示状态的观察结果只是将设置为正常状态的内容变暗,而不是使用正确的突出显示图像。

Normal:

突出显示(箭头仍然是白色,按钮意外变暗):

请不要发布有关使用的答案leftBarButtonItem or UIButton作为自定义视图。这两种方法都破坏了 iOS 7 上可用的滑动返回行为。

UPD:关于此问题的雷达#17481106。

UPD2:雷达#17481106 在 iOS 8 中修复。


目前苹果有buginteractivePopGestureRecognizer(这使得在推送动画上向后滑动后冻结导航控制器的视图,您将看到nested pop animation can result in corrupted navigation bar控制台中的警告),顺便说一句,我们可以做一个小黑客来解决这个错误。

这是一个对我来说效果很好的解决方案,

子类化 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
  

当用户在转换中间开始向后滑动时,弹出事件会堆积起来并“破坏”导航堆栈。我的解决方法是在推送转换期间暂时禁用手势识别器,并在新视图控制器加载时再次启用它。同样,使用 UINavigationController 子类会更容易。

之后就可以放心使用了item.leftBarButtonItem and UIButton作为自定义视图。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 7:如何为 UIControlStateHighlighted 设置 UIBarButtonItem backButtonBackgroundImage? 的相关文章

随机推荐