jjzjj

iOS 7 : How to set UIBarButtonItem backButtonBackgroundImage for UIControlStateHighlighted?

coder 2023-07-27 原文

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

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

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

正常:

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

请不要发布有关使用 leftBarButtonItemUIButton 作为自定义 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.leftBarButtonItemUIButton 作为自定义 View 。

关于iOS 7 : How to set UIBarButtonItem backButtonBackgroundImage for UIControlStateHighlighted?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23665841/

有关iOS 7 : How to set UIBarButtonItem backButtonBackgroundImage for UIControlStateHighlighted?的更多相关文章

随机推荐