【问题标题】:set custom back bar button universally with no title通用设置自定义后退栏按钮,没有标题
【发布时间】:2013-08-07 09:02:22
【问题描述】:

我想为应用中的所有控制器设置自定义后退栏按钮。我试过用这个:

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

它设置图像。没关系。但是,我真正想做的是,我只想要一个不包含任何标题等的后栏按钮的自定义按钮。上面的代码有效,但它添加了自动标题并调整后栏按钮项目的大小。我的需要是为应用程序中的所有控制器提供一个固定框架、无标题的后退栏按钮项。

【问题讨论】:

  • 你试过 barBtn.title=@""; ???
  • 这样做会隐藏整个按钮。
  • 如果将类型设置为 BarButtonItem 将无法获得自定义后退按钮的感觉。最好添加自定义 UIButton。

标签: iphone ios objective-c uinavigationbar uinavigationitem


【解决方案1】:

我已经解决了。只需在 UIViewController 上创建一个类别并将其导入 prefix.pch 文件。然后编写一个方法:customViewWillAppear: 并使用 viewWillAppear 方法对其进行 swizzle:

+(void)load{

Method viewWillAppear = class_getInstanceMethod(self, @selector(customViewWillAppear:));

Method customViewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
method_exchangeImplementations(viewWillAppear, customViewWillAppear);

}

将上述方法添加到该类别类。然后像这样实现您的 customViewWillAppear 方法:

-(void)customViewWillAppear:(BOOL)animated{
    [self customViewWillAppear:animated];
    if([self.navigationController.viewControllers indexOfObject:self] != 0  && !self.navigationItem.hidesBackButton){
        UIBarButtonItem *cancelBarButton = nil;
        UIButton* cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [cancelButton addTarget:self action:@selector(popViewControllerWithAnimation) forControlEvents:UIControlEventTouchUpInside];
        [cancelButton setBackgroundImage:[UIImage imageNamed:@"yourImage.png"] forState:UIControlStateNormal];
        [cancelButton sizeButtonToFit];

        cancelBarButton = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];

        NSMutableArray * leftButtons = [NSMutableArray arrayWithObject:cancelBarButton];
        [leftButtons addObjectsFromArray:self.navigationItem.leftBarButtonItems];
        [self.navigationItem setLeftBarButtonItem:nil];
        [self.navigationItem setLeftBarButtonItems:leftButtons];
    }

    [self.navigationItem setHidesBackButton:YES];
}
-(void)popViewControllerWithAnimation{
    [self.navigationController popViewControllerAnimated:YES];
}

现在,对于代码中的每个控制器,您都有一个自定义后退按钮。这花了我很多时间来实施和弄清楚。希望对大家也有帮助。

编辑: 请使用以下代码支持iOS7>后退功能;

UIImage *image = [UIImage imageForName:@"some_image"];
navBar.backIndicatorImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
navBar.backIndicatorTransitionMaskImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

创建一个基础视图控制器并添加以下代码;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}

【讨论】:

  • 非常感谢这段代码!到目前为止我发现的唯一问题是现在无法将视图控制器从左边缘拖动到右侧以将其从导航堆栈中弹出
  • 是的,对于装有 iOS 7 或更高版本的设备来说是这样。
  • 好的,我已经找到了解决这个问题的另一种方法,您需要将视图控制器设置为交互式弹出手势识别器的代理,其中self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;customViewWillAppear
  • 但是这个是一个黑客。我更喜欢使用外观代理:stackoverflow.com/a/20330647/1092167
  • 此外观代理不会阻止导航栏显示“后退”标题。
【解决方案2】:

我之前遇到过类似的问题,我到处寻找解决方案。

我发现的唯一一个可以解决您的问题的方法是在每个视图控制器中实现一个 UILeftBarButton 来执行弹出操作。

您可以按照自己的方式更改背景图像,但如果您将文本设置为 nil 或空文本 (""),您的按钮将不会显示。

您也无法更改 UIBackBarButton 的视图,只能更改文本(因此没有自定义按钮)。

【讨论】:

  • 我有几十个控制器,这个操作对我来说太贵了。
  • 您将无法更改后退按钮的背景并删除文本(Apple 在考虑本地化的同时做到了这一点,因为您不应该将文本添加到图像中,而是从代码中添加)
【解决方案3】:

我所做的是,使用外观代理将后退按钮标题标签 alpha 设置为零。

【讨论】:

  • 你能分享任何代码吗?我认为您无法访问 uibarbuttonitem 的标题标签。即使你这样做了,它只会设置标题的可见性,后退按钮仍然会根据标题调整其框架。
  • 我不在办公桌后面,但如果您将字体大小调整为 silly 0.1,它将无法检测到。使用[[UIBarButtonItem appearance] setTitleTextAttributes ...
【解决方案4】:

我的代码在ViewDidLoad:

// Set back button image
if ([[self.navigationController viewControllers] objectAtIndex:0] != self) {
    UIButton *btnBack = [UIButton buttonWithType:UIButtonTypeCustom];
    btnBack.frame = CGRectMake(0,0,38,30);
    [btnBack setBackgroundImage:[UIImage imageNamed:@"NavigationBarBackButton"] forState:UIControlStateNormal];
    [btnBack addTarget:self.navigationController action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *leftBtn = [[UIBarButtonItem alloc] initWithCustomView:btnBack];
    [self.navigationItem setLeftBarButtonItem:leftBtn];
}

【讨论】:

    【解决方案5】:

    你可以这样写一个类别,

    //
    //  UINavigationItem+BarAditions.h
    //
    //  Created by Satheeshwaran on on 7/5/13.
    //
    
    
    #import <Foundation/Foundation.h>
    
    
    @interface UINavigationItem (PersonaAddition)
    
    - (void)setCustomBackButton;
    
    @end
    
    
    //
    //  UINavigationItem+BarAditions.m
    //
    //  Created by Satheeshwaran on on 7/5/13.
    //
    
    #import "UINavigationItem+PersonaAddition.h"
    
    
    @implementation UINavigationItem (PersonaAddition)
    
    - (void)setCustomBackButton 
    {
        //customize ur back button here.
        UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
        backButton.frame=CGRectMake(0, 0, 60, 30);
        [backButton addTarget:target action:@selector(didPressLeftItem:) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        self.leftBarButtonItem = barItem;    
    
    }
    

    并在所有你的文件中导入这个类别,并在你所有的类中调用 setCustomBackButton。这对我来说很好,即使在 iOS 7 中也是如此。

    在所有类的 ViewDidLoad 中。

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        [self.navigationItem setCustomBackButton];
    
    }
    

    【讨论】:

      【解决方案6】:

      试试这个代码:

      UIButton *tempbtn = [[UIButton alloc] init];
      [tempbtn setImage:[UIImage imageNamed:@"testbtn.png"] forState:UIControlStateNormal];
      UIBarButtonItem *temp = [[UIBarButtonItem alloc] initWithCustomView:tempbtn];
      self.navigationItem.rightBarButtonItem = temp;
      

      【讨论】:

      • UIBarbuttonsystemItems的标题不需要设置,图片的标题也不需要设置。
      猜你喜欢
      • 2020-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 2016-04-01
      • 1970-01-01
      相关资源
      最近更新 更多