Создание кнопки со стрелкой влево (например, стиль «назад» UINavigationBar) на панели инструментов UIToolbar - PullRequest
286 голосов
/ 22 октября 2008

Я бы хотел создать кнопку «назад» влево-стрелка в UIToolbar.

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

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

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

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

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

Ответы [ 23 ]

127 голосов
/ 22 февраля 2009

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

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

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

У меня хорошо работает.


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

// 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];
46 голосов
/ 04 августа 2010

Метод Unicode

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

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 символ Unicode и то, что вы хотите. Вот запись для черный треугольник, указывающий влево .

Результат

The result

37 голосов
/ 06 августа 2010

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

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

// 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, не используйте недокументированные функции и все такое. Есть только шесть поддерживаемых типов кнопок, и это не один из них.

36 голосов
/ 18 сентября 2013

enter image description here

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

РЕДАКТИРОВАТЬ:

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

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

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

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

-(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];
18 голосов
/ 24 февраля 2009

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

14 голосов
/ 21 августа 2014

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

Стандарт:

Standard system back arrow

Apple SD Gothic Neo

Apple SD Gothic Neo < character

В Xcode:

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

Ref @ staticVoidMan's answer to Back-like arrow на iOS 7

8 голосов
/ 15 января 2016

back arrow

Если вы не хотите беспокоиться о файлах изображений, форму стрелки можно нарисовать в подклассе 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

7 голосов
/ 31 января 2011
    self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

У меня работает. Я использовал это, когда у меня было больше вкладок, чем могло поместиться на панели вкладок, и контроллер представления, выдвинутый из «More», отвергал leftBarButtonItem в его viewDidLoad.

4 голосов
/ 20 ноября 2009

В библиотеке 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;
4 голосов
/ 24 февраля 2009

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

...