首页 文章

没有 Headers 的UINavigationBar自定义后退按钮

提问于
浏览
221

如何在没有 Headers 的情况下自定义iOS 7及更高版本中的导航后退按钮? (即只带箭头)

self.navigationItem.leftBarButtonItem = self.editButtonItem;

我只是想知道他们是否有任何self.backButtonItem;

要么

这样的事情?

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
                   initWithBarButtonSystemItem:UIBarButtonSystemItemBACK 
                   target:self action:@selector(back)];

30 回答

  • 22

    这实际上非常简单,这就是我的工作:

    目标C.

    // Set this in every view controller so that the back button displays back instead of the root view controller name
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    

    斯威夫特2

    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
    

    斯威夫特3

    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    

    将此行放在正在推送到堆栈的视图控制器中( the previous view controller ) . 新推的视图控制器后退按钮现在将显示您为initWithTitle添加的内容,在本例中为空字符串 .

  • 0

    我找到了一种简单的方法来使用iOS单箭头制作我的后退按钮 .

    让我们假设你有一个导航控制器从ViewB转到ViewA . 在IB中,选择ViewA的导航栏,您应该看到以下选项: Headers ,提示和后退按钮 .

    ViewA navigate bar options

    ViewA navigate bar options

    诀窍是在 previous 视图控制器(视图A)的选项中选择命运视图控制器后退按钮 Headers (ViewB) . 如果您未填写选项"Back Button",iOS将自动将 Headers "Back"与 previous 视图控制器的 Headers 放在一起 . 因此,您需要使用单个空格填充此选项 .

    Fill space in "Back Button" option

    Fill space in "Back Button" option

    The Result:

    The Result:

  • 2

    只需使用图像!

    OBJ-C

    - (void)viewDidLoad {
         [super viewDidLoad];
         UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Icon-Back"]
                                                                                            style:UIBarButtonItemStylePlain
                                                                                           target:self.navigationController
                                                                                           action:@selector(popViewControllerAnimated:)];
         self.navigationItem.leftBarButtonItem = backButton;
    }
    

    SWIFT 4

    let backBTN = UIBarButtonItem(image: UIImage(named: "Back"), 
                                  style: .plain, 
                                  target: navigationController, 
                                  action: #selector(UINavigationController.popViewController(animated:)))
    navigationItem.leftBarButtonItem = backBTN
    navigationController?.interactivePopGestureRecognizer?.delegate = self
    

    ICON-Back.png

    Icon-Back

    Icon-Back@2x.png

    Icon-Back@2x

    Icon-Back@3x.png

    Icon-Back@23x

  • 6

    iOS7有新的界面规则,因此在推UIView时最好至少保留后退箭头 . 以编程方式更改“后退”文本非常容易 . 只需在推送视图之前添加此代码(如果您使用的是StoryBoards,则添加prepareForSegue):

    -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
          self.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"NEW TITLE" style:UIBarButtonItemStylePlain target:nil action:nil];
    }
    

    这将更改默认的“返回”文本,但会保留iOS7样式的后退箭头 . 您还可以在推动视图之前更改后退箭头的色调颜色:

    - (void)viewDidLoad{
         //NavBar background color:
         self.navigationController.navigationBar.barTintColor=[UIColor redColor];
    //NavBar tint color for elements:
         self.navigationController.navigationBar.tintColor=[UIColor whiteColor];
    }
    

    希望这对你有所帮助!

  • 0

    你不需要做什么 . 您可以通过故事板本身实现相同的目标 .

    只需转到根导航控制器并给出一个空格 . 切记不要你想要没有 Headers 的后退按钮的控制器,而是根导航控制器 .

    As per the image below. This works for iOS 7 and iOS 8

  • 0

    虽然Kyle Begeman's answer完全可以解决问题,但是在每个视图控制器中都可以使用这些代码是非常烦人的 . 我最终得到了一个简单的 UINavigationItem 类别 . 小心,这里是龙!对不起,我的意思是,调酒:

    #import <objc/runtime.h>
    
    @implementation UINavigationItem (ArrowBackButton)
    
    static char kArrowBackButtonKey;
    
    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            Method m1 = class_getInstanceMethod(self, @selector(backBarButtonItem));
            Method m2 = class_getInstanceMethod(self, @selector(arrowBackButton_backBarButtonItem));
            method_exchangeImplementations(m1, m2);
        });
    }
    
    - (UIBarButtonItem *)arrowBackButton_backBarButtonItem {
        UIBarButtonItem *item = [self arrowBackButton_backBarButtonItem];
        if (item) {
            return item;
        }
    
        item = objc_getAssociatedObject(self, &kArrowBackButtonKey);
        if (!item) {
            item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:NULL];
            objc_setAssociatedObject(self, &kArrowBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        return item;
    }
    
    @end
    
  • 6

    EDIT: 2014-04-09: As I gained reputations, I feel sorry because I don't use this trick any more. I recommend Kyle's answer. Also notice that the self of self.navigationItem.backBarButtonItem isn't the view controller the back button is displayed, but the previous view controller to be went back.

    如果您不需要为前一个视图控制器提供 Headers 文本,只需用空白字符串填充 Headers ;

    self.navigationItem.title = @"";
    [self.navigationController pushViewController:viewController animated:YES];
    

    这将防止在推动的视图控制器上显示带有V形的“后退” .

    编辑:即使您使用非空白 Headers 文本,在 viewWillAppear: 工作中设置上一个视图控制器的 Headers 除了 Headers 可以在视图控制器弹出时闪烁闪烁 . 我认为"The twitter app"似乎做了更微妙的黑客以避免闪烁 .

  • 26

    这有效,但它会删除上一项的 Headers ,即使你回弹它:

    self.navigationController.navigationBar.topItem.title = @"";
    

    只需在推送的View Controller的 viewDidLoad 上设置此属性即可 .

  • 9

    这就是我这样做的方式,也是最简单,最有效,最清晰的方法 .

    如果嵌入 Navigation Controller ,这是有效的

    Swift 3

    viewDidLoad 中,我将此添加到View Controller,您希望后退按钮只是箭头 .

    if let topItem = self.navigationController?.navigationBar.topItem {
       topItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
    

    这与@Kyle Begeman的答案的不同之处在于,您在视图控制器上调用此选项,您希望后退按钮只是箭头,而不是推送堆栈视图控制器 .

  • 28

    您无法按照自己的方式访问导航backButtonItem,您需要创建自己的后退按钮,如下所示:

    - (void)loadView
    {
        [super loadView];
        UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 44.0f, 30.0f)];
        [backButton setImage:[UIImage imageNamed:@"back.png"]  forState:UIControlStateNormal];
        [backButton addTarget:self action:@selector(popVC) forControlEvents:UIControlEventTouchUpInside];
        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    }
    

    当然:

    - (void) popVC{
      [self.navigationController popViewControllerAnimated:YES];
    }
    
  • 1

    来自iOS6的简单黑客也适用于iOS7:

    [UIBarButtonItem.appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];
    

    Edit: 不要使用这个黑客 . 请参阅评论了解详情 .

  • 3

    Target:UINavigationBar 上的所有后退按钮自定义为白色图标

    Steps: 1.在AppDelete的"didFinishLaunchingWithOptions"方法中:

    UIImage *backBtnIcon = [UIImage imageNamed:@"navBackBtn"];
    
    
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
        [UINavigationBar appearance].tintColor = [UIColor whiteColor];
        [UINavigationBar appearance].backIndicatorImage = backBtnIcon;
        [UINavigationBar appearance].backIndicatorTransitionMaskImage = backBtnIcon;
    }else{
    
        UIImage *backButtonImage = [backBtnIcon resizableImageWithCapInsets:UIEdgeInsetsMake(0, backBtnIcon.size.width - 1, 0, 0)];
        [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage  forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    
        [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -backButtonImage.size.height*2) forBarMetrics:UIBarMetricsDefault];
    }
    

    2.在普通超级 ViewController 类的 viewDidLoad 方法中:

    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
            UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@""
                                                                         style:UIBarButtonItemStylePlain
                                                                        target:nil
                                                                        action:nil];
            [self.navigationItem setBackBarButtonItem:backItem];
        }else{
            //do nothing
        }
    
  • 193

    你可以用它 . 只需添加一个 UIButton 作为 UIBarButtonItem 的custumview,这对我来说非常有效 .

    试试下面的代码

    self.navigationItem.leftBarButtonItem=[self backButton];
    
    
    - (UIBarButtonItem *)backButton
    {
        UIImage *image = [UIImage imageNamed:@"back-btn.png"];
        CGRect buttonFrame = CGRectMake(0, 0, image.size.width, image.size.height);
    
        UIButton *button = [[UIButton alloc] initWithFrame:buttonFrame];
        [button addTarget:self action:@selector(backButtonPressed) forControlEvents:UIControlEventTouchUpInside];
        [button setImage:image forState:UIControlStateNormal];
    
        UIBarButtonItem *item= [[UIBarButtonItem alloc] initWithCustomView:button];
    
        return item;
    }
    
  • 20

    所有答案都没有解决问题 . 在每个视图控制器中设置后退按钮 Headers 并向 Headers 添加偏移量仍然使下一个视图控制器 Headers 向右移动是不可接受的 .

    这是使用方法调配的方法,只需为UINavigationItem创建新的扩展

    import UIKit
    
    extension UINavigationItem {
        public override class func initialize() {
    
        struct Static {
            static var token: dispatch_once_t = 0
        }
    
        // make sure this isn't a subclass
        if self !== UINavigationItem.self {
            return
        }
    
        dispatch_once(&Static.token) {
            let originalSelector = Selector("backBarButtonItem")
            let swizzledSelector = #selector(UINavigationItem.noTitleBackBarButtonItem)
    
            let originalMethod = class_getInstanceMethod(self, originalSelector)
            let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
    
            let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
    
            if didAddMethod {
                class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod)
            }
        }
    }
    
    // MARK: - Method Swizzling
    
    struct AssociatedKeys {
        static var ArrowBackButtonKey = "noTitleArrowBackButtonKey"
    }
    
    func noTitleBackBarButtonItem() -> UIBarButtonItem? {
        if let item = self.noTitleBackBarButtonItem() {
            return item
        }
    
        if let item = objc_getAssociatedObject(self, &AssociatedKeys.ArrowBackButtonKey) as? UIBarButtonItem {
            return item
        } else {
            let newItem = UIBarButtonItem(title: " ", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
            objc_setAssociatedObject(self, &AssociatedKeys.ArrowBackButtonKey, newItem as UIBarButtonItem?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            return newItem
        }
    }
    }
    
  • 1

    创建一个 UILabel ,其中包含所需的根视图控制器 Headers ,并将其分配给视图控制器的 navigationItem.titleView .

    现在将 Headers 设置为空字符串,然后您推送的下一个视图控制器将有一个没有文本的后退按钮 .

    self.navigationItem.titleView = titleLabel; //Assuming you've created titleLabel above
    self.title = @"";
    
  • 2
    // add left bar button item
    
    try this code:
    
    - (void)viewDidLoad
    { 
        [super viewDidLoad];
    
       UIImage* image_back = [UIImage imageNamed:@"your_leftarrowImage.png"];
        CGRect backframe = CGRectMake(250, 9, 15,21);
        UIButton *backbutton = [[UIButton alloc] initWithFrame:backframe];
        [backbutton setBackgroundImage:image_back forState:UIControlStateNormal];
        [backbutton addTarget:self action:@selector(Btn_back:)
             forControlEvents:UIControlEventTouchUpInside];
        [backbutton setShowsTouchWhenHighlighted:YES];
        UIBarButtonItem *backbarbutton =[[UIBarButtonItem alloc] initWithCustomView:backbutton];
        self.navigationItem.leftBarButtonItem=backbarbutton;
        [backbutton release];
    
    }
    -(IBAction)Btn_back:(id)sender
    {
        [self.navigationController popViewControllerAnimated:YES];
    
    }
    
  • 21

    您可以创建子类UINavigationController,将其自身设置为委托,并在委托方法 navigationController:willShowViewController:animated: 中设置backBarButtonItem

    @interface Custom_NavigationController : UINavigationController <UINavigationControllerDelegate>
    
    @end
    
    @implementation Custom_NavigationController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.delegate = self;
    }
    
    #pragma mark - UINavigationControllerDelegate
    
    - (void)navigationController:(UINavigationController *)navigationController     willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    }
    
    @end
    
  • 57

    将 Headers 设置为空

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@""  style:UIBarButtonItemStyleDone target:self action:@selector(handleBack:)];
    [backButton setTintColor:Color_WHITE];
    [self.navigationItem setBackBarButtonItem:backButton];
    

    改变背面图像

    UIImage *backImg = [[UIImage imageNamed:@"ic_back_white"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    [UINavigationBar appearance].backIndicatorImage = backImg;
    [UINavigationBar appearance].backIndicatorTransitionMaskImage = backImg;
    
  • 1

    我一直在使用这个解决方案iOS 5左右没有任何问题 . 我创建了一个实用程序函数,我在视图控制器中调用它 . 您需要在viewDidLoad或之后的任何点执行此操作 .

    void updateBackButtonTextForViewController(UIViewController *viewController, NSString *text)
    {
        if(! viewController.navigationItem.backBarButtonItem)
        {
            viewController.navigationItem.backBarButtonItem =
            [[UIBarButtonItem alloc] initWithTitle:text
                                             style:UIBarButtonItemStylePlain
                                            target:nil action:nil];
        }
        else
        {
            viewController.navigationItem.backBarButtonItem.title = text;
        }
    }
    

    在某些情况下,导航项可能已经存在,在其他情况下需要创建 . 这可以解决这两种情况,而不会弄乱导航项目 Headers . 它允许您通过简单地传入 @"" 来删除 Headers .

  • 3

    我在viewDidLoad中应用了以下代码,它可以工作:

    // this will set the back button title
    self.navigationController.navigationBar.topItem.title = @"Test";
    
     // this line set the back button and default icon color  
    
    //[[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor blackColor]];
    
    this line change the back default icon to your custom icon
    [[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"menuicon"]]];
    

    只是为了更新我使用矢量图标

  • 1

    对我有用的唯一方法是:

    navigationController?.navigationBar.backItem?.title = ""
    

    更新:

    当我将segue动画标志更改为true(以前是假的)时,对我有用的唯一方法是:

    navigationController?.navigationBar.topItem?.title = ""
    
  • 2

    如果您有两个ViewController(FirstVC,SecondVC)嵌入导航控制器,并且您希望在SecondVC中只有后退箭头 .

    你可以在FirstVC的ViewDidLoad中试试这个

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
    }
    

    然后当你进入SecondVC时,你会看到只有后箭头

  • 0

    如果设置tintColor Of NavigationBar,请添加不带 Headers 的自定义后退按钮图像,色调颜色将反映图像颜色 . 请关注此苹果文档链接 .

    https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/UIKitUICatalog/index.html#//apple_ref/doc/uid/TP40012857-UIView-SW7

    UINavigationItem *navItem = [[UINavigationItem alloc] init];
       navBar.tintColor = self.tintColor;
    
       UIImage *myImage = [UIImage imageNamed:@"left_arrow.png"];
         myImage = [myImage              imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    
         UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:myImage style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonFunction:)];
         navItem.leftBarButtonItem = leftButton;
    
        navBar.items = @[ navItem ];
    
  • 1

    检查这个答案

    How to change the UINavigationController back button name?

    title 文本设置为 string ,其中一个空格如下所示

    title = " "
    

    没有足够的声誉来添加评论:)

  • 1

    SWIFT 4

    对于那些希望创建自定义后退按钮以及删除其 Headers 的用户,请在视图控制器中使用以下代码来推送新的代码:

    self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "close")
    self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "close")
    self.navigationItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    

    要获得更普遍的使用,请执行以下操作:

    • 创建一个通用函数,如下所示:
    func addCustomizedBackBtn(navigationController: UINavigationController?, navigationItem: UINavigationItem?) {
        navigationController?.navigationBar.backIndicatorImage = UIImage(named: "close")
        navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "close")
        navigationItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
    
    • 然后在视图控制器中使用它,如下所示:
    addCustomizedBackBtn(navigationController: self.navigationController, navigationItem: self.navigationItem)
    
  • 2

    在您的第一个ViewController的prepareForSegue:方法中,您将 Headers 视图设置为@“”,因此当按下下一个视图时,它将显示以前的ViewController Headers ,该 Headers 将为@“” .

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        self.navigationItem.title = @" ";
    }
    

    唯一的问题是,当您点击后退按钮时,您之前的视图将没有 Headers ,因此您可以在viewWillAppear上再次添加它:

    -(void)viewWillAppear:(BOOL)animated{
       self.navigationItem.title = @"First View Title";
    }
    

    我不太喜欢这个解决方案,但它有效,我没有找到其他方法来做到这一点 .

  • 304

    要添加到上面的Thomas C's answer,有时放置一个空格不起作用,您必须不断添加空格 .

    empty bar button

    当你在“导航项目”下看到“条形按钮项目 - ”时,你会知道你成功了 . 这是在文档大纲(编辑器 - >显示文档大纲)中 . 看到上面的图片后,您可以删除一些空格,看看它是否仍然有效 .

  • 6
    - (id)initWithCoder:(NSCoder *)aDecoder
    {
        self = [super initWithCoder:aDecoder];
        if (self) {
            // Custom initialization
            self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    
        }
        return self; 
    }
    

    就像Kyle Begeman一样,您可以在根视图控制器上添加上面的代码 . 将应用所有子视图控制器 . 另外,在initWithCoder:方法中添加它,您可以在xib,storyboard或基于代码的方法中应用根视图控制器的样式 .

  • 0
    • 将新的UIBarButtonItem添加到左边的UINavigationItem

    • 更改UIBarButtonItem如何使用

    • 现在,单击UINavigationItem并从出口向左滑动barBackButtonItem到左UIBarButtonItem

    enter image description here

  • 1

    您可以将该类别放在AppDelegate.m文件中 . 从UINavigation中的所有默认后退按钮中删除文本 . 如果需要,只有箭头"<"或设置自定义图像 .

    Objective-C的:

    ...

    @结束

    @implementation UINavigationItem (Extension)
    
    - (UIBarButtonItem *)backBarButtonItem {
    
        return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    }
    
    @end
    

相关问题