Пользовательская кнопка возврата в 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
?
Ответы
Ответ 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)
}
Ответ 6
Смотрите этот ответ здесь: Как создать backBarButtomItem с пользовательским представлением для UINavigationController
Вам просто нужно установить свойство backBarButtonItem
на navigationController до, нажав на viewController. Установка свойства backBarButtonItem
в методе viewController viewDidLoad
(например) не работает.
Ответ 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