it-swarm.com.ru

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

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

self.navigationItem.leftBarButtonItem = self.editButtonItem;

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

ИЛИ ЖЕ 

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

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

Это на самом деле довольно легко, вот что я делаю:

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

Swift 2

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

Swift 3

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

Поместите эту строку в контроллер представления, который помещается в стек (предыдущий контроллер представления). Недавно нажатая кнопка назад контроллера представления покажет все, что вы положили для initWithTitle, который в данном случае является пустой строкой. 

304
Kyle Begeman

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

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

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

ViewA navigate bar options

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

Заполнить пробел в опции «Кнопка назад»

Fill space in "Back Button" option

Результат:

The Result:

195
Tom Calmon

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

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

[email protected]

Icon-Back@2x

[email protected]

Icon-Back@23x

62
mt81

в iOS7 появились новые правила интерфейса, поэтому лучше, по крайней мере, удерживать стрелку назад, когда вы нажимаете UIView .... Очень легко программно изменить текст «назад». Просто добавьте этот код, прежде чем отправлять представление (или prepareForSegue, если вы используете 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];
}

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

28
Anibal Itriago

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

Просто зайдите в корневой навигационный контроллер и оставьте пробел. Помните не для контроллера, который вы хотели кнопку назад без заголовка, но для корневого контроллера навигации.

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

26
Swaroop S

В то время как ответ Кайла Бегемана полностью справляется с задачей, довольно неприятно иметь этот код в каждом возможном контроллере представления. Я закончил с простой категорией 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
22
Nicky

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

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

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

Это предотвратит отображение «назад» с помощью шеврона на контроллере push-сообщения.

Правка: Даже если вы используете непустой текст заголовка, установка заголовка предыдущего контроллера представления в viewWillAppear: работает, за исключением того, что заголовок может мигать, когда контроллер представления отключился. Я думаю, что «приложение Twitter», кажется, делает более тонкий взлом, чтобы избежать мерцания.

21
hiroshi

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

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

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

20
Guto Araujo

Это то, как я это делаю, и самый простой, эффективный и понятный способ сделать это.

Это работает, если встроить в 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 состоит в том, что вы вызываете это на контроллере представления, который вы хотите, чтобы кнопка «назад» была просто стрелкой, а не на контроллере представления с выталкивающим стеком.

9
r_19

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

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

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

6
zh.

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

Цель: Настроить все кнопки возврата на 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 общего супер 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
    }
6
Jagie

Все ответы не решают проблему. Недопустимо устанавливать заголовок кнопки «Назад» в каждом контроллере представления, и добавление смещения к заголовку по-прежнему приводит к сдвигу заголовка следующего 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
    }
}
}
3
jakub wolanski

вы можете использовать это. Это прекрасно работает для меня, просто добавив 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;
}
3
Abhilash Reddy Kallepu
 // 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];

}
2
Paresh Hirpara

Вы можете создать подкласс 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
2
Nate Potter

Установить обратно название пустым

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;
2
warriorg

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

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

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

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

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

Обновление: 

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

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

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

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

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

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

1
Yu-Lin Wang

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

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

1
Dima

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

Просто для обновления я использую Векторный Icon

1
Hajra Qamar

Swift 4

Для тех, кто хочет создать пользовательские кнопки «Назад» и удалить их заголовок, используйте следующий фрагмент кода в контроллере вида, который выдвигает новый:

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)

Для более универсального использования сделайте следующее:

  1. Создайте универсальную функцию следующим образом:

    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)
    }
    
  2. Затем используйте его в контроллерах представления следующим образом:

    addCustomizedBackBtn(navigationController: self.navigationController, navigationItem: self.navigationItem)
    
1
Nino Bouchedid

Проверьте этот ответ

Как изменить имя кнопки возврата UINavigationController?

установите title текст в string с одним пробелом, как показано ниже

title = " "

Не хватает репутации, чтобы добавлять комментарии :)

1
Leojin

Если вы установите 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 ];
1
Nazish Ali

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

Objective-C:

...

@конец

@implementation UINavigationItem (Extension) 

- (UIBarButtonItem *) backBarButtonItem {

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

 @ end
0
Aleksandr B.

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

-(void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.title = @"Previous Title";
}

-(void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.title = @"";
}
0
WaleedAmmari

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

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

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

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

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

0
Alejandro Figueroa

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

empty bar button

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

0
Rog182

Я написал расширение, чтобы сделать это проще: 

extension UIViewController {

    /// Convenience for setting the back button, which will be used on any view controller that this one pushes onto the stack
    @objc var backButtonTitle: String? {
        get {
            return navigationItem.backBarButtonItem?.title
        }
        set {
            if let existingBackBarButtonItem = navigationItem.backBarButtonItem {
                existingBackBarButtonItem.title = newValue
            }
            else {
                let newNavigationItem = UIBarButtonItem(title: newValue, style:.plain, target: nil, action: nil)
                navigationItem.backBarButtonItem = newNavigationItem
            }
        }
    }

}
0
Mark Bridges

Установить название кнопки «Назад» как пустую строку.

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

0
Georgekutty Joy
  1. Добавить новый UIBarButtonItem в UINavigationItem слева
  2. Измените UIBarButtonItem, как хотите использовать
  3. Теперь нажмите UINavigationItem и проведите barBackButtonItem из розеток влево UIBarButtonItem

 enter image description here

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

Как и Кайл Бегеман, вы добавляете приведенный выше код в свой контроллер корневого представления. Все вспомогательные контроллеры будут применены. Кроме того, добавив это в initWithCoder: метод, вы можете применить стиль для корневых контроллеров представления в xib, раскадровке или подходах, основанных на коде.

0
Chris So