Пользовательская кнопка UINavigationBar без заголовка

Как я могу настроить кнопку перехода назад в iOS 7 и выше без заголовка? (т.е. только со стрелкой)

self.navigationItem.leftBarButtonItem = self.editButtonItem;

Мне просто интересно, если у них есть self.backButtonItem;

ИЛИ

что-то вроде этого?

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

Ответ 1

На самом деле это довольно просто, вот что я делаю:

Цель 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];

Свифта

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

Поместите эту строку в контроллер представления, который нажимает на стек. Вновь нажатая кнопка возврата контроллера отобразит все, что вы положили для initWithTitle, который в этом случае является пустой строкой.

Ответ 2

Я нашел простой способ сделать свою кнопку с единственной стрелкой iOS.

Предположим, что у вас есть контроллер навигации, идущий в ViewA из ViewB. В IB выберите панель навигации ViewA, вы должны увидеть следующие параметры: Название, кнопка подсказки и кнопка возврата.

Параметры панели навигации ViewA

ViewA navigate bar options

Трюк - это выбрать название кнопки управления заголовком вашего судьбы (ViewB) в настройках диспетчера представлений предыдущий (вид A). Если вы не заполните опцию "Back Button", iOS автоматически поместит заголовок "Назад", с названием заголовка предыдущий. Итак, вам нужно заполнить эту опцию одним пространством.

Заполнить пространство в опции "Назад"

Fill space in "Back Button" option

Результат:

The Result:

Ответ 3

Просто используйте изображение!

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

Icon-back.png

Icon-Back

[email protected]

Icon-Back@2x

[email protected]

Icon-Back@23x

Ответ 4

iOS7 имеет новые правила интерфейса, поэтому лучше удерживать хотя бы обратную стрелку, когда вы нажимаете UIView. Слишком легко изменить "назад" текст программно. Просто добавьте этот код, прежде чем нажимать на него (или подготовьте FORSegue, если вы используете StoryBoards):

-(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];
}

Надеюсь, это поможет вам!

Ответ 5

Ничего особенного вам не нужно делать. Вы можете добиться того же самого через раскадровку.

Просто перейдите к корневому навигационному контроллеру и дайте пробел. Не забывайте о том, что контроллер вам нужен кнопка "Назад" без заголовка, но к корневому навигационному контроллеру.

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

Ответ 6

В то время как ответ Кайла Бегемана полностью делает трюк, довольно неприятно иметь этот код во всех возможных контроллерах. Я закончил с простой категорией UINavigationItem. Опасайтесь, вот драконы! Извините, я имею в виду, swizzling:

#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

Ответ 7

EDIT: 2014-04-09: Как я получил репутацию, мне жаль, потому что я больше не использую этот трюк. Я рекомендую ответить Кайлу. Также обратите внимание, что self of self.navigationItem.backBarButtonItem не является контроллером представления, а кнопка назад отображается, но предыдущий контроллер просмотра должен вернуться.

Если вам не нужно иметь текст заголовка для предыдущего контроллера представлений, просто заполните заголовок пустой строкой;

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

Это предотвратит показ "назад" с шевром на контроллере с нажатым представлением.

РЕДАКТИРОВАТЬ: даже вы используете непустой текст заголовка, задавая заголовок предыдущего контроллера представления в viewWillAppear:, за исключением того, что заголовок может мерцать в мигающем режиме, когда вызывается контроллер. Я думаю, что "приложение Twitter", похоже, делает более тонкий взлом, чтобы избежать мерцания.

Ответ 8

Это работает, но оно удалит заголовок предыдущего элемента, даже если вы вернетесь к нему:

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

Просто установите это свойство на viewDidLoad нажатого View Controller.

Ответ 9

Вот как я это делаю и простейший, работает и наиболее понятный способ сделать это.

Это работает, если вставить на Navigation Controller

Swift 3

В viewDidLoad Я добавляю это в контроллер просмотра, чтобы кнопка "Назад" была просто стрелкой.

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

Разница в ответе @Kyle Begeman заключается в том, что вы вызываете это на контроллере представления, что вы хотите, чтобы кнопка возврата была просто стрелкой, а не на контроллере представления толкающего стека.

Ответ 10

У вас нет доступа к навигации 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];
}

Ответ 11

Простой взлом из iOS6 также работает на iOS7:

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

Edit: Не используйте этот хак. См. Комментарий для деталей.

Ответ 12

Цель: настройка всей кнопки "Назад" на UINavigationBar на белый значок

Шаги: 1. в методе "didFinishLaunchingWithOptions" AppDelete:

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. в методе viewDidLoad общего класса super ViewController:

 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
    }

Ответ 13

вы можете использовать это. Это отлично работает для меня, просто добавив UIButton как custumview для UIBarButtonItem.

Попробуйте приведенный ниже код

    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;
}

Ответ 14

Все ответы не решают проблему. Недопустимо отбрасывать название кнопки в каждом контроллере представления, а добавление смещения к заголовку делает следующий сдвиг названия View Controller вправо.

Вот метод, использующий метод swizzling, просто создайте новое расширение для 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
    }
}
}

Ответ 15

Создайте UILabel с заголовком, который вы хотите для своего контроллера корневого представления, и назначьте его контроллеру представления navigationItem.titleView.

Теперь установите заголовок в пустую строку, и следующий контроллер воспроизведения, который вы нажимаете, будет иметь кнопку возврата без текста.

self.navigationItem.titleView = titleLabel; //Assuming you've created titleLabel above
self.title = @"";

Ответ 16

 // 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];

}

Ответ 17

Установить пустой заголовок

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;

Ответ 18

Я использую это решение с 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;
    }
}

В некоторых случаях элемент навигации может уже существовать, в других случаях его необходимо создать. Это объясняет оба этих случая, не возившись с заголовком навигационного элемента. Это позволяет удалить заголовок, просто перейдя в @"".

Ответ 19

Я применил следующий код в 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"]]];

Просто для обновления я использую значок "Значок"

Ответ 20

Вы можете подклассифицировать UINavigationController, установить себя как делегат и установить backBarButtonItem в методе делегата navigationController:willShowViewController:animated:

@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

Ответ 21

Если у вас есть два контроллера ViewController (FirstVC, SecondVC) в навигационном контроллере, и вы хотите, чтобы в SecondVC была только стрелка назад.

Вы можете попробовать это В FirstVC ViewDidLoad

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

Затем, когда вы нажимаете SecondVC, вы увидите, что есть только стрелка назад

Ответ 22

Если вы установили tintColor Of NavigationBar, добавьте пользовательское обратное изображение кнопки без заголовка, цвет оттенка которого будет отражать цвет изображения. Пожалуйста, следуйте этой ссылке документа Apple.

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 ];

Ответ 24

В методе prepareForSegue: вашего первого ViewController вы задаете заголовок вида @ ", поэтому при следующем нажатии на него будет отображаться предыдущий заголовок ViewController, который будет @" ".

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

Единственная проблема заключается в том, что когда вы нажимаете кнопку "Назад", ваш предыдущий вид не будет иметь заголовок, поэтому вы можете добавить его снова в viewWillAppear:

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

Мне не очень нравится это решение, но оно работает, и я не нашел другого способа сделать это.

Ответ 25

Чтобы добавить к Thomas C answer выше, иногда установка одного места не работает, и вам нужно продолжать добавлять пробелы.

empty bar button

Вы узнаете, что вам удалось, когда вы видите пункт "Элемент панели бара" - под "Элементом навигации". Это в схеме документа (Редактор- > Показать структуру документа). Как только вы увидите вышеприведенное изображение, вы можете удалить несколько пробелов и посмотреть, все ли работает.

Ответ 26

- (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, раскадровки или кода.

Ответ 27

Единственный способ, который работал у меня:

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

ОБНОВЛЕНИЕ:

Когда я изменил флаг анимации segue на true (раньше это было ложно), единственный способ, который работал у меня:

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

Ответ 28

  • Добавить новый UIBarButtonItem в UINavigationItem влево
  • Изменить UIBarButtonItem как использовать
  • Теперь нажмите UINavigationItem и проведите по экрану barBackButtonItem из выходов влево UIBarButtonItem

введите описание изображения здесь

Ответ 29

Вы можете поместить эту категорию в файл AppDelegate.m. для удаления текста со всех кнопок возврата по умолчанию в UINavigation. Только стрелка "<" или настроить пользовательское изображение, если вам нужно.

Objective-c:

...

@end

@implementation UINavigationItem (Extension)

- (UIBarButtonItem *)backBarButtonItem {

    return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}

@end

Ответ 30

Установить название элемента кнопки в виде пустой строки.

[self.navigationController.navigationBar.backItem setTitle: @""];