Создание кнопки со стрелкой влево (например, стиль UINavigationBar "назад" ) на UIToolbar

Мне бы хотелось создать кнопку "назад" влево-в виде стрелки в UIToolbar.

Насколько я могу судить, единственный способ получить один из них - оставить UINavigationController по умолчанию и использовать его для элемента левой панели. Но я не могу найти его как UIBarButtonItem, поэтому я не могу сделать его в стандартном UIToolbar, хотя они очень похожи на UINavigationBar s.

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

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

Обновление: ПОЖАЛУЙСТА, ОСТАНОВИТЕ, уклонившись от вопроса и предлагая, чтобы я не спрашивал об этом и должен использовать UINavigationBar. Мое приложение - Instapaper Pro. Он показывает только нижнюю панель инструментов (чтобы сэкономить место и увеличить читаемую область содержимого), и я хочу поместить в обратную сторону кнопку "Назад" в форме стрелки влево.

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

Ответ 1

Я использовал следующий psd, который я получил из http://www.teehanlax.com/blog/?p=447

http://www.chrisandtennille.com/pictures/backbutton.psd

Затем я создал пользовательский UIView, который я использую в свойстве customView элемента панели инструментов.

Хорошо работает для меня.


Изменить: Как было отмечено PrairieHippo, маралджо обнаружил, что, используя следующий простой код, трюк (требуется пользовательский образ в комплекте) должен сочетаться с этим ответом, Итак, вот дополнительный код:

// Creates a back button instead of default behaviour (displaying title of previous screen)
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"]
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(backAction)];

tipsDetailViewController.navigationItem.leftBarButtonItem = backButton;
[backButton release];

Ответ 2

Метод Unicode

Я думаю, что намного проще просто использовать символ Юникода, чтобы выполнить задание. Вы можете просмотреть стрелки по googling либо Unicode Triangles или Unicode Arrows. Начиная с iOS6 Apple изменил персонаж, чтобы быть символом эможи с границей. Чтобы отключить границу, я добавляю переключатель Unicode Variation Selector > 0xFE0E.

NSString *backArrowString = @"\U000025C0\U0000FE0E"; //BLACK LEFT-POINTING TRIANGLE PLUS VARIATION SELECTOR

UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.leftButtonItem = backBarButtonItem;

Блок кода предназначен только для демонстрации. Он будет работать на любой кнопке, которая принимает NSString.

Для полного списка символов найдите Google для символа Юникода и что хотите. Вот запись для Черный левый треугольник.

Результат

The result

Ответ 3

ПРЕДУПРЕЖДЕНИЕ: Сообщается, что это не будет работать на iOS 6. Это может работать только в более старых версиях ОС. Очевидно, по крайней мере, у одного разработчика было отклонено их приложение для использования этого трюка (см. Комментарии). Используйте на свой риск. Использование изображения (см. Ответ выше) может быть более безопасным решением.

Это можно сделать без добавления собственных файлов изображений, используя кнопку sekr1t типа 101, чтобы получить правильную форму. Для меня трюк выяснял, что я могу использовать "initWithCustomView" для создания элемента кнопки бара. Я лично нуждался в этом для динамического навигатора, а не на панели инструментов, но я тестировал его с помощью панели инструментов, и код почти такой же:

// create button
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape!
[backButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:@"Back" forState:UIControlStateNormal];

// create button item -- possible because UIButton subclasses UIView!
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

// add to toolbar, or to a navbar (you should only have one of these!)
[toolbar setItems:[NSArray arrayWithObject:backItem]];
navItem.leftBarButtonItem = backItem;

Если вы делаете это на панели инструментов, вам придется настроить, как вы устанавливаете элементы, но это зависит от остальной части вашего кода, и я оставляю это как упражнение для читателя.: P Этот образец работал у меня (скомпилирован и запущен).

Бла-бла, прочитайте HIG, не используйте недокументированные функции и все такое. Там всего шесть поддерживаемых типов кнопок, и это не один из них.

Ответ 4

enter image description here

Прежде всего, вам нужно найти изображение кнопки "Назад". Я использовал красивое приложение под названием Extractor, которое извлекает все графики с iPhone. В iOS7 мне удалось получить изображение под названием UINavigationBarBackIndicatorDefault, и оно было черного цвета, так как мне нужен красный оттенок Я меняю цвет на красный с помощью Gimp.

EDIT:

Как было отмечено в btate в своем комментарии, нет необходимости менять цвет с помощью редактора изображений. Следующий код должен сделать трюк:

imageView.tint = [UIColor redColor];
imageView.image = [[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Затем я создал представление, содержащее imageView с этой стрелкой, метку с пользовательским текстом и над представлением у меня есть кнопка с действием. Затем я добавил простую анимацию (затухание и перевод).

Следующий код моделирует поведение кнопки "Назад", включая анимацию.

-(void)viewWillAppear:(BOOL)animated{
        UIImageView *imageView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"]];
        [imageView setTintColor:[UIColor redColor]];
        UILabel *label=[[UILabel alloc] init];
        [label setTextColor:[UIColor redColor]];
        [label setText:@"Blog"];
        [label sizeToFit];

        int space=6;
        label.frame=CGRectMake(imageView.frame.origin.x+imageView.frame.size.width+space, label.frame.origin.y, label.frame.size.width, label.frame.size.height);
        UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0, label.frame.size.width+imageView.frame.size.width+space, imageView.frame.size.height)];

        view.bounds=CGRectMake(view.bounds.origin.x+8, view.bounds.origin.y-1, view.bounds.size.width, view.bounds.size.height);
        [view addSubview:imageView];
        [view addSubview:label];

        UIButton *button=[[UIButton alloc] initWithFrame:view.frame];
        [button addTarget:self action:@selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
        [view addSubview:button];

        [UIView animateWithDuration:0.33 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            label.alpha = 0.0;
            CGRect orig=label.frame;
            label.frame=CGRectMake(label.frame.origin.x+25, label.frame.origin.y, label.frame.size.width, label.frame.size.height);
            label.alpha = 1.0;
            label.frame=orig;
        } completion:nil];

        UIBarButtonItem *backButton =[[UIBarButtonItem alloc] initWithCustomView:view];
}

- (void) handleBack:(id)sender{
}

EDIT:

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

UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleBack:)];
[view addGestureRecognizer:tap];
[view setUserInteractionEnabled:YES];

Ответ 5

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

Ответ 6

Чтобы сделать UIButton со стрелкой довольно близко (я не дизайнер;) к обратной стрелке системы iOS 7:

Стандарт:

Standard system back arrow

Apple SD Gothic Neo

Apple SD Gothic Neo < character

В Xcode:

  • Сосредоточьтесь на поле значения заголовка кнопки (или любого другого вида/элемента управления с текстовым контентом)
  • Открыть Правка → Специальные символы
  • Выберите группу скобок и дважды щелкните значок '<' символ
  • Изменить шрифт на: Apple SD Gothic Neo, Обычный с желаемым размером (например, 20)
  • Измените цвет, как вам нравится

Ref @staticVoidMan answer для напоминающей стрелку на iOS 7

Ответ 7

назад стрелка

Если вы не хотите беспокоиться о файлах изображений, форма стрелки может быть нарисована в подклассе UIView со следующим кодом:

- (void)drawRect:(CGRect)rect {
    float width = rect.size.width;
    float height = rect.size.height;
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, width * 5.0/6.0, height * 0.0/10.0);
    CGContextAddLineToPoint(context, width * 0.0/6.0, height * 5.0/10.0);
    CGContextAddLineToPoint(context, width * 5.0/6.0, height * 10.0/10.0);
    CGContextAddLineToPoint(context, width * 6.0/6.0, height * 9.0/10.0);
    CGContextAddLineToPoint(context, width * 2.0/6.0, height * 5.0/10.0);
    CGContextAddLineToPoint(context, width * 6.0/6.0, height * 1.0/10.0);
    CGContextClosePath(context);

    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillPath(context);
}

где вид стрелки пропорционален ширине 6,0 и высоте 10,0

Ответ 8

    self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

Работает для меня. Я использовал это, когда у меня было больше вкладок, после чего они могли поместиться на панели вкладок, а контроллер представления, нажатый из "Больше", переопределил элемент leftBarButtonItem в своем представленииDidLoad.

Ответ 9

Вы можете найти исходные изображения, извлекая их из Other.artwork в UIKit ${SDKROOT}/System/Library/Frameworks/UIKit.framework/Other.artwork. Сообщество моддинга имеет некоторые инструменты для их извлечения, здесь. Как только вы извлечете изображение, вы можете написать код, чтобы перекрасить его по мере необходимости и установить его как изображение кнопки. Независимо от того, действительно ли вы можете отправить такую ​​вещь (поскольку вы внедряете производные произведения искусства), может быть немного рискованно, поэтому, возможно, вы хотите поговорить с адвокатом.

Ответ 10

В библиотеке Three20 есть способ сделать это:

  UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle: @"Title" style:UIBarButtonItemStylePlain 
                                                                target:self action:@selector(foo)];

  UIColor* darkBlue = RGBCOLOR(109, 132, 162);

  TTShapeStyle* style = [TTShapeStyle styleWithShape:[TTRoundedLeftArrowShape shapeWithRadius:4.5] next:
    [TTShadowStyle styleWithColor:RGBCOLOR(255,255,255) blur:1 offset:CGSizeMake(0, 1) next:
    [TTReflectiveFillStyle styleWithColor:darkBlue next:
    [TTBevelBorderStyle styleWithHighlight:[darkBlue shadow]
                                     shadow:[darkBlue multiplyHue:1 saturation:0.5 value:0.5]
                                      width:1 lightSource:270 next:
    [TTInsetStyle styleWithInset:UIEdgeInsetsMake(0, -1, 0, -1) next:
    [TTBevelBorderStyle styleWithHighlight:nil shadow:RGBACOLOR(0,0,0,0.15)
                                        width:1 lightSource:270 next:nil]]]]]];

  TTView* view = [[[TTView alloc] initWithFrame:CGRectMake(0, 0, 80, 35)] autorelease];
  view.backgroundColor = [UIColor clearColor];
  view.style = style;
  backButton.customView = view;


  self.navigationItem.leftBarButtonItem = backButton;

Ответ 11

Я обнаружил, что использование следующего простого кода делало трюк (требуется собственное изображение в комплекте):

// Creates a back button instead of default behaviour (displaying title of previous screen)
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"]
                                                                   style:UIBarButtonItemStyleBordered
                                                                  target:self
                                                                  action:@selector(backAction)];

    tipsDetailViewController.navigationItem.leftBarButtonItem = backButton;
    [backButton release];

Ответ 12

Вот что я в итоге сделал после поиска всех этих решений и других. Он использует растягиваемый png, извлеченный из изображений UIKit. Таким образом, вы можете установить текст на все, что вы liek

// Generate the background images
UIImage *stretchableBackButton = [[UIImage imageNamed:@"UINavigationBarDefaultBack.png"] stretchableImageWithLeftCapWidth:14 topCapHeight:0];
UIImage *stretchableBackButtonPressed = [[UIImage imageNamed:@"UINavigationBarDefaultBackPressed.png"] stretchableImageWithLeftCapWidth:13 topCapHeight:0];
// Setup the UIButton
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setBackgroundImage:stretchableBackButton forState:UIControlStateNormal];
[backButton setBackgroundImage:stretchableBackButtonPressed forState:UIControlStateSelected];
NSString *buttonTitle = NSLocalizedString(@"Back", @"Back");
[backButton setTitle:buttonTitle forState:UIControlStateNormal];
[backButton setTitle:buttonTitle forState:UIControlStateSelected];
backButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 2, 1); // Tweak the text position
NSInteger width = ([backButton.titleLabel.text sizeWithFont:backButton.titleLabel.font].width + backButton.titleEdgeInsets.right +backButton.titleEdgeInsets.left);
[backButton setFrame:CGRectMake(0, 0, width, 29)];
backButton.titleLabel.font = [UIFont boldSystemFontOfSize:13.0f];
[backButton addTarget:self action:@selector(yourSelector:) forControlEvents:UIControlEventTouchDown];
// Now add the button as a custom UIBarButtonItem
UIBarButtonItem *backButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];
self.navigationItem.leftBarButtonItem = backButtonItem;

Ответ 13

Это легко сделать с конструктором интерфейса в Xcode 5.x

Result

  • используйте Панель инструментов и Элемент панели инструментов из Библиотека объектов

    Components

  • в кнопке Инспектор атрибутов отредактируйте Изображение. с обратным изображением кнопки

    Attributes inspector

Готово!

Ответ 14

Я пытался сделать то же самое, но я хотел, чтобы кнопка возврата была в панели навигации. (На самом деле мне нужна кнопка "назад", что сделало бы больше, чем только возврат, поэтому мне пришлось использовать свойство leftBarButtonItem). Я попробовал, что предложил AndrewS, но в навигационной панели он не будет выглядеть так, как должен, поскольку UIButton был отброшен в UIBarButtonItem.

Но я нашел способ обойти это. Я на самом деле просто поместил UIView в UIButton и установил customView для UIBarButtonItem. Вот код, если кому-то это нужно:

// initialize button and button view
UIButton *backButton = [UIButton buttonWithType:101];
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, backButton.frame.size.width, backButton.frame.size.height)];

[backButton addTarget:self action:@selector(backButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:@"Back" forState:UIControlStateNormal];
[backButtonView addSubview:backButton];

// set buttonview as custom view for bar button item
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
self.navigationItem.leftBarButtonItem = backButtonItem;

// push item to navigationbar items
[self.navigationController.navigationBar setItems:[NSArray arrayWithObject:backButtonItem]];

Ответ 15

Чтобы создать изображение для UIToolbar, сделайте png в фотошопе, и ГДЕ ЕСТЬ НИЖНИЙ цвет, он помещает его в белый цвет и где он альфа = 0, он оставляет его в покое.

SDK фактически помещает границу вокруг значка, который вы сделали, и превращает его в белый, не делая ничего.

Посмотрите, это то, что я сделал в Photoshop для моей кнопки "вперед" (очевидно, поменял ее на кнопку "Назад" ):

http://twitpic.com/1oanv

и это было похоже на интерфейс Builder

http://twitpic.com/1oaoa

Ответ 16

Решение БЕЗ использования png. На основе этого ответа SO: Добавление маленькой стрелки в правую сторону ячейки в iPhone TableView Cell

Просто переверните UITableViewCell по горизонтали!

UIButton *btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 5, 70, 20)];

// Add the disclosure
CGRect frm;
UITableViewCell *disclosure = [[UITableViewCell alloc] init];
disclosure.transform = CGAffineTransformScale(CGAffineTransformIdentity, -1, 1);
frm = self.btnBack.bounds;
disclosure.frame = CGRectMake(frm.origin.x, frm.origin.y, frm.size.width-25, frm.size.height);
disclosure.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
disclosure.userInteractionEnabled = NO;
[self.btnBack addSubview:disclosure];

// Add the label
UILabel *lbl = [[UILabel alloc] init];
frm = CGRectOffset(self.btnBack.bounds, 15, 0);
lbl.frame = frm;
lbl.textAlignment = NSTextAlignmentCenter;
lbl.text = @"BACK";
[self addSubview:lbl];

Ответ 17

Ну, вам не нужно иметь другую кнопку для каждого размера, вы можете использовать [UIImage stretchableImageWithLeftCapWidth:topCapHeight:], но единственное, что я нашел, это пользовательские изображения.

Ответ 18

Если вы хотите не рисовать его самостоятельно, вы можете использовать недокументированный класс: UINavigationButton со стилем 1. Это может, конечно, остановить ваше приложение от одобрения... /John

Ответ 19

У меня была аналогичная проблема, и вышла одна библиотека PButton. И образец - это кнопка обратной навигации, как кнопка, которую можно использовать в любом месте, как на индивидуальной кнопке.

Что-то вроде этого: enter image description here

Ответ 20

Пример в Swift 3 с предыдущей и следующей кнопками в правом верхнем углу.

let prevButtonItem = UIBarButtonItem(title: "\u{25C0}", style: .plain, target: self, action: #selector(prevButtonTapped))
let nextButtonItem = UIBarButtonItem(title: "\u{25B6}", style: .plain, target: self, action: #selector(nextButtonTapped))
self.navigationItem.rightBarButtonItems = [nextButtonItem, prevButtonItem]

Ответ 21

Swift

// create button
    var backButton = UIButton(type: 101)

    // left-pointing shape!
    backButton.addTarget(self, action: #selector(self.backAction), for: .touchUpInside)
    backButton.setTitle("Back", for: .normal)

    // create button item -- possible because UIButton subclasses UIView!
    var backItem = UIBarButtonItem(customView: backButton)

    // add to toolbar, or to a navbar (you should only have one of these!)
    toolbar.items = [backItem]
    navItem.leftBarButtonItem = backItem

Ответ 22

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

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back"
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(yourSelectorGoesHere:)];
self.navigationItem.backBarButtonItem = backButton;

Это все, что вам нужно сделать:)

Ответ 23

Зачем ты это делаешь? Если вы хотите что-то похожее на панель навигации, используйте UINavigationBar.

Панели инструментов имеют определенный визуальный стиль, связанный с ними. Руководства по человеческому интерфейсу для состояния iPhone:

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

Затем он дает несколько визуальных примеров примерно квадратных значков без текста. Я бы настоятельно рекомендовал вам следовать HIG.