Пользовательская кнопка возврата в UINavigationController - PullRequest
18 голосов
/ 17 августа 2010

Для приложения, которое я разрабатываю, мне нужно отобразить пользовательскую кнопку возврата на панели навигации.У меня есть актив кнопки в виде изображения PNG, и я пишу этот код:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    backButton.frame = CGRectMake(0, 0, 79, 29.0);
    [backButton setImage:[UIImage imageNamed:@"button_back.png"] forState:UIControlStateNormal];
    self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];

}

Когда я нажимаю этот контроллер вида, пользовательская кнопка не отображается, ивместо этого я получаю стандартную кнопку возврата с названием этого контроллера вида внутри.

Вещи, которые я уже пробовал:

  1. Удвойте проверку правильности создания кнопки backButton, добавивэто к иерархии представления.Он отображается правильно.
  2. В том же методе изменил свойство title navigationItem и подтвердил, что он изменяет (как и ожидалось) содержимое моей кнопки возврата.

Кто-нибудь может определить, что я делаю не так?Кому-нибудь удалось использовать пользовательское изображение в качестве кнопки возврата с UINavigationController?

Ответы [ 10 ]

18 голосов
/ 05 декабря 2012

Начиная с iOS 5, это просто:

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

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

13 голосов
/ 30 мая 2013

Я пересылаю свое решение из https://stackoverflow.com/a/16831482/171933:

Я создаю простую категорию для UIViewController:

UIViewController + ImageBackButton.h

#import <UIKit/UIKit.h>

@interface UIViewController (ImageBackButton)

- (void)setUpImageBackButton;

@end

UIViewController + ImageBackButton.m

#import "UIViewController+ImageBackButton.h"

@implementation UIViewController (ImageBackButton)

- (void)setUpImageBackButton
{
    UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 34, 26)];
    [backButton setBackgroundImage:[UIImage imageNamed:@"back_arrow.png"] forState:UIControlStateNormal];
    UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = barBackButtonItem;
    self.navigationItem.hidesBackButton = YES;
}

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

@end

Теперь все, что вам нужно сделать, это #import UIViewController+ImageBackButton.h во всех ваших контроллерах представления или в пользовательском базовом классе контроллера представлениячто другие ваши контроллеры представления наследуют и реализуют метод viewWillAppear::

- (void)viewWillAppear:(BOOL)animated
{
    [self setUpImageBackButton];
}

Вот и все.Теперь у вас есть кнопка возврата изображения везде.Без границы.Наслаждайтесь!

5 голосов
/ 27 сентября 2010

Свойство backBarButtonItem работает как задумано, но оно всегда добавляет свою стандартную форму и цвет кнопки в зависимости от оттенка навигационной панели.

Вы можете настроить текст, но не заменить изображение.

Один из обходных путей, как предложил Эндрю Пулио, - использовать вместо него leftBarButtonItem, но вместо этого я остановился на стандартной кнопке.

4 голосов
/ 24 сентября 2014

Разве это не самое простое решение - просто создать его из раскадровки с любым изображением или цветами и просто перетащить новое действие на контроллер?

Swift Code

@IBAction func backButton(sender: AnyObject) {
    self.navigationController?.popViewControllerAnimated(true)
}
3 голосов
/ 17 августа 2010

Смущает backBarButtonItem это не то, что вы ищете.

Он просто управляет заголовком на кнопке «Назад» для следующего контроллера просмотра. То, что вы хотите, это установить leftBarButtonItem на вашу собственную кнопку возврата.

2 голосов
/ 22 сентября 2016

Ответ Йоханнеса Фаренкруга работает, но заднее изображение появилось бы в очень проволочном положении.

Здесь я нашел лучший способ разместить изображение в нужном месте:

Убедитесь, что выПолучите заднее изображение размером 24x24 (@ 1x), я называю его backImage

Выполните следующий код, когда ваше приложение запустится

UINavigationBar.appearance().barTintColor = nil
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics: .Default)
1 голос
/ 10 февраля 2015

Я не думаю, что сам ViewController должен знать что-либо о своей кнопке возврата Согласно ООП, это ответственность контейнераViewController, в который вставлен ваш контроллер представления, например UINavigationController.

Создайте подкласс вашего NavigationController и перегрузите в нем метод суперкласса следующим образом:

@implementation STONavigationController

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [super pushViewController:viewController animated:animated];
    if ([self.viewControllers indexOfObject:viewController] != NSNotFound &&
        [self.viewControllers indexOfObject:viewController] > 0){
        UIImage *img = [UIImage imageNamed:@"back-1"];
        UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, img.size.width * 2, img.size.height * 2)];
        [backButton setBackgroundImage:img forState:UIControlStateNormal];
        UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
        viewController.navigationItem.leftBarButtonItem = barBackButtonItem;
        viewController.navigationItem.hidesBackButton   = YES;
    }
}

- (void)popCurrentViewController
{
    [self popViewControllerAnimated:YES];
}

@end 
1 голос
/ 25 августа 2011

См. Этот ответ здесь: Как создать backBarButtomItem с настраиваемым представлением для UINavigationController

Вам просто нужно установить свойство backBarButtonItem на navigationController до того, как нажмет viewController. Установка свойства backBarButtonItem в методе viewController viewDidLoad (например) не работает.

0 голосов
/ 12 апреля 2017

Как подсказал @pgb, вы можете использовать leftBarButtonItem вместо элемента кнопки назад.И чтобы удалить элемент кнопки возврата по умолчанию, установите для него значение nil следующим образом:

navigationController?.navigationBar.backIndicatorImage = nil
navigationController?.navigationBar.backIndicatorTransitionMaskImage = nil

let button = UIButton.init(type: .custom)
button.imageView?.contentMode = UIViewContentMode.scaleAspectFit
button.setImage(UIImage.init(named: "top_back"), for: UIControlState.normal)
button.frame = CGRect.init(x: 0, y: 0, width: 75, height: 50) 
button.addTarget(self, action: #selector(handleBackButton), for: .touchUpInside)

let barButton = UIBarButtonItem.init(customView: button)
self.navigationItem.leftBarButtonItem = barButton
0 голосов
/ 23 марта 2011

Просто создайте UIBarButtonItem вместо встроенного UIButton в UIBarButtonItem. Работает отлично!

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"button_back.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];

self.navigationItem.backBarButtonItem = backButton; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...