【问题标题】:Setting a Custom Image for a Back Button on UINavigationBar为 UINavigationBar 上的后退按钮设置自定义图像
【发布时间】:2012-06-16 16:59:29
【问题描述】:

我正在尝试为后退按钮设置自定义图像,当新视图被推入堆栈时,该按钮会自动放置在导航栏上。

我尝试在父viewController的viewDidLoad中添加以下内容:

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:@"BackButton.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

我也尝试了以下方法:

UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"BackButton.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];
    self.navigationItem.backBarButtonItem = btn;

使用 UIAppearance 会产生非常奇怪的结果:

【问题讨论】:

  • 除了您每次都必须这样做之外,backBarButtonItem 方法是否成功?
  • 不,两种方法都不成功。我最终不得不通过隐藏 backButton 然后设置标准按钮并将视图从堆栈中弹出来以一种 hacky 的方式来完成它。不理想。
  • 嗯...您也可以尝试将后退按钮文本设置为@" ",或者在仍使用第一种方法时将后退按钮文本颜色设置为透明。
  • 这看起来像您创建的后退按钮上已经有文本...如果是这样.. 方法是错误的... ios 将扩展按钮以适应后退按钮文本并且还将把文字放在上面

标签: iphone objective-c xcode uinavigationcontroller uibutton


【解决方案1】:

试试这个代码

UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
UIImage *backBtnImage = [UIImage imageNamed:@"BackBtn.png"]  ;  
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];  
[backBtn addTarget:self action:@selector(goback) forControlEvents:UIControlEventTouchUpInside];  
backBtn.frame = CGRectMake(0, 0, 54, 30);  
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn] ;  
self.navigationItem.leftBarButtonItem = backButton;

然后像这样定义 goback 方法

- (void)goback
{
    [self.navigationController popViewControllerAnimated:YES];
}

【讨论】:

  • 这几乎正是我所做的工作。我隐藏了 backButton 并使用 leftBarButton 来显示我的自定义图像,然后将视图从堆栈中弹出。但这并不理想。
  • 这是测试代码,我在很多应用中都使用过,尝试复制粘贴我的代码,可能你做错了什么,请重新检查
  • 我的代码略有不同,因为我正在使用自定义视图(即)UIButton 初始化 UIBarButtonItem
  • 我并不是说代码错误。我已经使用了同样的方法。我要说的是,这并不是真正的 /correct/ 方式,因为 iOS 5 有一个 UIApperance 属性来为后退按钮设置自定义图像。
  • 好的,IOS 5 有不同的方式来设置后退按钮的图像是正确的,但他们并没有说你不能自己创建后退按钮,所以我认为你也可以使用该代码: )
【解决方案2】:

从 iOS 7.0 开始,API backIndicatorImage 中有一个新方法。如果您不希望图像被拉伸以适合文本(例如,如果您想要一个固定大小的自定义后退箭头),您可以使用它而不是 setBackButtonBackgroundImage 。这是 swift 中的一个示例:

let image = UIImage(named: "back_button")
    
UINavigationBar.appearance().backIndicatorImage = image
UINavigationBar.appearance().backIndicatorTransitionMaskImage = image

您可以使用此技巧隐藏按钮中的文本:

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -66), for: .default)

对于 Swift 5

var backButtonImage = UIImage(named: "back_button")

backButtonImage = backButtonImage?.stretchableImage(withLeftCapWidth: 15, topCapHeight: 30) UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)

【讨论】:

  • 您还可以隐藏 StoryBoard 上的文本,在执行 sugue(push) 的控制器中,您可以将 NavigationBar 的后退按钮标题(属性 on属性检查器)。
  • 如何使图像适合?现在我得到一个不太合适的大图像......
【解决方案3】:

这是我正在使用的代码,可以在我自己的 iOS 5 应用程序中完美运行。此代码来自应用委托中的application:didFinishLaunchingWithOptions:

UIImage * backButtonImage = [UIImage imageNamed: @"back-button-image"];
backButtonImage = [backButtonImage stretchableImageWithLeftCapWidth: 15.0 topCapHeight: 30.0];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage: backButtonImage forState: UIControlStateNormal barMetrics: UIBarMetricsDefault];

您可能需要使用可拉伸的图像,其中左侧的“点”是左帽


或在 Swift 中

let backButtonImage = UIImage(named: "back-button-image")
backButtonImage = backButtonImage?.stretchableImageWithLeftCapWidth(15, topCapHeight: 30)
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, forState: .Normal, barMetrics: .Default)

【讨论】:

  • 使用 backButtonImage = [backButtonImage resizableImageWithCapInsets:UIEdgeInsetsZero];而不是 stretchableImageWithLeftCapWidth,因为此方法已被弃用。
【解决方案4】:

iOS 8+ Swift 版本(可以毫不费力地转换为 ObjC)。此方法保留了与标准后退按钮相关的导航栏的所有优点和行为(推/弹出动画、交互式弹出手势等)

// Call the code ONE TIME somewhere on app launch to setup custom back button appearance
UINavigationBar.appearance().tintColor = UIColor.blackColor()
// If you need custom positioning for your back button, in this example button will be 1 px up compared to default one
// Also only vertical positioning works, for horizontal add offsets directly to the image
let backImageInsets = UIEdgeInsetsMake(0, 0, -1, 0)
// Get image, change of rendering (so it preserves offsets made in file), applying offsets
let backImage = UIImage(named: "YourButtonImageAssetFileName")?.imageWithRenderingMode(.AlwaysOriginal).imageWithAlignmentRectInsets(backImageInsets)
// Setting images
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage

// Call EACH TIME BEFORE pushing view controller if you don't need title near your back button arrow
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
// Push controller
self.navigationController?.pushViewController(vc, animated: true)

【讨论】:

    【解决方案5】:

    试试下面的代码,它对我有用:

    [[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back-button-image"]];
    [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back-button-image"]];
    

    【讨论】:

      【解决方案6】:

      此代码适用于 Swift 5XCode 10

      将此代码添加到 AppDelegate 的 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 以应用于所有视图控制器:

      //Custom back button
          let barButtonItemAppearance = UIBarButtonItem.appearance()
          barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
          barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .highlighted)
          let backImg: UIImage = UIImage(named: "back")!
          barButtonItemAppearance.setBackButtonBackgroundImage(backImg, for: .normal, barMetrics: .default)
      
          let image = UIImage()
      
          UINavigationBar.appearance().backIndicatorImage = image
          UINavigationBar.appearance().backIndicatorTransitionMaskImage = image
      

      【讨论】:

        【解决方案7】:

        在公共类中编写此方法,并从要在其中绘制的控制器中调用它。

        (UIButton *)drawNavigationBarBackButton:(UIViewController*)viewController 
        {
        
            UIImage *navBackImage = nil;
        
            UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
             navBackImage = [UIImage imageNamed:@"Back_Button"];
        
            [backButton setImage:navBackImage forState:UIControlStateNormal];
            UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];
            viewController.navigationItem.leftBarButtonItem = leftButton;
        
            return backButton;
        }
        
        
        
        call from controller class and setting action
        
        - (void)viewDidLoad {
        
        [super viewDidLoad];
        
         UIButton *backButton = [CommonClass drawNavigationBarBackButton:self];
            [backButton addTarget:self action:@selector(onTapBackButton) forControlEvents:UIControlEventTouchUpInside];
        }
        
        - (void)onTapBackButton 
        {
            [self.navigationController popViewControllerAnimated:YES];
        }
        

        【讨论】:

          【解决方案8】:

          这对我有用:

          let button1 = UIBarButtonItem(
              image: #imageLiteral(resourceName: "back_arrow"), 
              style: .plain, 
              target: self, 
              action: #selector(self.backBtnTapped(_:))
          )
          self.navigationItem.leftBarButtonItem  = button1
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-12-09
            • 2020-11-23
            • 1970-01-01
            • 1970-01-01
            • 2013-03-18
            • 1970-01-01
            • 2013-09-23
            相关资源
            最近更新 更多