【问题标题】:iOS 7: Custom Back Indicator Image PositioniOS 7:自定义后退指示器图像位置
【发布时间】:2014-10-04 16:49:52
【问题描述】:

我无法正确设置自定义后退指示器图像。指标不居中!

这是一张照片:

我正在didFinishLaunchingWithOptions: 方法中设置指示器图像...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

   UIImage *image = [UIImage imageNamed:@"Back"];
   [UINavigationBar appearance].backIndicatorImage = image;
   [UINavigationBar appearance].backIndicatorTransitionMaskImage = image;

   return YES;
}

如何才能居中?

p.s 我已经读过这个Custom back indicator image in iOS 7 not vertically centered,但实际上它对我不起作用。

【问题讨论】:

    标签: ios ios7 uinavigationbar


    【解决方案1】:
     UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 2, 0);
     UIImage *backArrowImage = [[UIImage imageNamed:@"Back"] imageWithAlignmentRectInsets:insets];
    
     [[UINavigationBar appearance] setBackIndicatorImage:backArrowImage];
     [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:backArrowImage];
    

    【讨论】:

    • 这项技术有效,但奇怪的是我需要在底部添加一个插图,以将图像向下移动。
    • 这似乎适用于垂直定位,但不适用于水平定位。如何调整水平位置?
    • 在 Swift 中,它适用于水平方向,但我首先设置了遮罩和 backArrowImage,但不确定它是否有意义。 let backArrow: UIImage = UIImage.whiteBackArrow.withRenderingMode(.alwaysOriginal).withAlignmentRectInsets(.init(top: 0, left: -10, bottom: 0, right: 0))
    【解决方案2】:

    发生这种情况是因为您只是在 UINavigationView 中更改 Back Indicator 的图像源,而不是框架。 看,当 UINavigationView 创建时,Back Indicator 的框架设置为保存默认 iOS 7 后退按钮图像的大小。默认的后退按钮图像比你的大,这就是它看起来没有对齐的原因。

    要解决此问题,您必须重置后退指示器的框架以保持图像的大小。另一种选择是创建一个具有正确帧大小和图像的 UIButton 并分配给 UIBarButtonItem。然后,您可以将 UINavigationItem 中的 backBarButtonItem 替换为您创建的新 UIBarButtonItem。

    【讨论】:

    • 感谢人的有用解释!但是如何重置后退指示器的框架?
    • 实际上,您必须使用具有新框架和图像的 UIButton 创建一个新的 UIBarButtonItem,并分配给您的 UINavigationItem。虽然,你可以做一些更快更容易的事情。使您的后退按钮的图像与默认的 iOS 7 后退按钮的图像大小相同。您不需要实际拉伸您的按钮,只需创建一个与 iOS 默认后退按钮大小相同的图像,并将您的按钮放在它的中心。这样,您的按钮图像将在顶部和底部有空格,使其与默认按钮的大小相同。只是一些 Photoshop 工作 =)
    • 或者,如果你仍然想创建一个自定义 UIBarButtonItem,这里有一个很好的例子:appgroup.co.uk/adding-a-uibarbuttonitem-with-a-custom-image
    • 越简单越好。所以我使用 Sketch App 使图像适合后指示器视图的大小。效果很好!
    • 我发现iOS9.2垂直23px很细
    【解决方案3】:

    这就是我使用 Appearance API 处理问题的方式,效果很好。 更改 backButtonBackgroundImage 时,图像会自动跨 barButtonItem 拉伸,因此我们必须使用 resizableImageWithCapInsets: 将其调整回原来的大小。 要将其放置在 barButtonItem 内,我们然后使用 imageWithAlignmentRectInsets 在其周围添加大写字母。然后使用 setBackButtonBackgroundImage:forState:barMetrics 分配它。

    只要玩数字,你就会找到正确的位置。

    int imageSize = 24;
    UIImage *barBackBtnImg = [[[UIImage imageNamed:@"backButton"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, imageSize, 0, 0)] imageWithAlignmentRectInsets:UIEdgeInsetsMake(0, -10, 0, -10)];
    [[UIBarButtonItem appearance] setBackButtonBackgroundImage:barBackBtnImg forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    

    【讨论】:

      【解决方案4】:

      这个解决方案在 Swift 2.1 中对我有用。 iOS 9.2.1。 (XCode 7.2) 在 iPhone 上的纵向模式。我已经在模拟器 iPhone 5 和 6+ 上对其进行了测试,它也可以正常工作。

      import UIKit
      
      class EVEMainNaviVC: UINavigationController
      {
          override func viewWillAppear(animated: Bool)
          {
              super.viewWillAppear(animated)
          }
      
      override func viewDidLoad()
      {
          super.viewDidLoad()
          self.view.backgroundColor = APP_BACKGROUND_COLOR
          self.setupAppNaviagtionBar()
      }
      
      
      private func setupAppNaviagtionBar()
      {
          dispatch_async(dispatch_get_main_queue())
          { () -> Void in
              self.navigationBar.setHeight(55.0)
              self.navigationBar.translucent        = false
              self.navigationBar.alpha              = 1.0
              self.navigationBar.barTintColor       = UIColor.whiteColor()
              let newBackButtonImageInset                         = UIEdgeInsetsMake(0, 0, -6, 0)
              let newBackButtonImage                              = UIImage(named: "back")?.imageWithAlignmentRectInsets(newBackButtonImageInset)
              self.navigationBar.backIndicatorImage               = newBackButtonImage
              self.navigationBar.backIndicatorTransitionMaskImage = newBackButtonImage
              self.navigationBar.tintColor = CUSTOM_BUTTON_COLOR
          }
      }
      }
      

      【讨论】:

      • 这是在实际导航栏实例上设置后退按钮时。当尝试使用 UINavigationBar 外观进行全局设置时,会出现问题中描述的问题。
      【解决方案5】:

      我找到了我见过的最简单的解决方案。只有三件事。

      1. 覆盖 UINavigationBar 并在您的 UINavigationController 中使用它

        let navigationController = UINavigationController(navigationBarClass: NavigationBar.self, toolbarClass: nil)
        navigationController.viewControllers = [viewController]
        
      2. 设置您的指示图像:

        backIndicatorImage = #imageLiteral(resourceName: "back")
        backIndicatorTransitionMaskImage = #imageLiteral(resourceName: "back")
        
      3. 在您的自定义 UINavigationBar 类中实现 layoutSubviews。

        override func layoutSubviews() {
            super.layoutSubviews()
        
            subviews.forEach { (view) in
                if let imageView = view as? UIImageView {
                    if imageView.image == backIndicatorImage || imageView.image == backIndicatorTransitionMaskImage {
                        view.frame.origin.y = floor((frame.height - view.frame.height) / 2.0)
                    }
                }
            }
        }
        

      就是这样。 :)

      【讨论】:

      • 问题是关于外观,而不是关于使用自定义类
      【解决方案6】:

      我的目标是定位后退按钮图像而不干扰UINavigationItem 的子视图。所以,我所做的是为UIImage 创建一个扩展,在图像周围添加一个填充。

      extension UIImage {
          public func imageWith(padding: UIEdgeInsets) -> UIImage {
              let origin = CGPoint(x: padding.left, y: padding.top)
              let sizeWithPadding = CGSize(width: padding.left + size.width + padding.right, height: padding.top + size.height + padding.bottom)
      
              UIGraphicsBeginImageContextWithOptions(sizeWithPadding, false, 0.0)
              draw(in: CGRect(origin: origin, size: size))
      
              let imageWithPadding = UIGraphicsGetImageFromCurrentImageContext() ?? self
              UIGraphicsEndImageContext()
      
              return imageWithPadding
          }
      }
      

      例如:如果要将图像移动到顶部,则将相应的填充添加到底部。 .imageWith(padding: UIEdgeInsets(top: 0, left: 0, bottom: 2, right: 0))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-25
        • 2013-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多