Подтвердить что ты не робот

Пользовательская кнопка возврата в UINavigationController

Для приложения, которое я разрабатываю, мне нужно отобразить пользовательскую кнопку "Назад" в панели навигации. У меня есть свойство кнопки в виде 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];

}

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

Я переношу свое решение из fooobar.com/questions/300099/...:

Я создаю простую категорию на 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];
}

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

Ответ 4

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

Он просто управляет заголовком на задней кнопке для следующего контроллера вида. Вы хотите установить leftBarButtonItem на пользовательскую кнопку возврата.

Ответ 5

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

Swift Code

@IBAction func backButton(sender: AnyObject) {
    self.navigationController?.popViewControllerAnimated(true)
}

Ответ 7

Я не думаю, что сам ViewController должен ничего знать о своей кнопке возврата В соответствии с OOP это несет ответственность за контейнерViewController, в который вставлен ваш контроллер просмотра, например UINavigationController.

Подкласс your navigationController и перегрузка в нем метода superClass следующим образом:

@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 

Ответ 8

Johannes Fahrenkrug Ответ работает, но обратное изображение появится в очень проводной позиции.

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

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

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

UINavigationBar.appearance().barTintColor = nil
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics: .Default)

Ответ 9

Просто создайте UIBarButtonItem вместо встроенного UIButton в UIBarButtonItem. Прекрасно работает!

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

self.navigationItem.backBarButtonItem = backButton; 

Ответ 10

Как показано в @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