it-swarm.com.ru

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

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

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

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

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

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

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

286
Marco

Я использовал следующий 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];
127
PyjamaSam

Метод Юникода

Я думаю, что гораздо проще просто использовать символ Юникода, чтобы выполнить работу. Вы можете просматривать стрелки, прибегая к помощи либо Треугольники Юникода , либо Стрелки Юникода . Начиная с iOS6 Apple изменил персонажа на смайлика с рамкой. Чтобы отключить границу, я добавляю 0xFE0E nicode 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

46
Cameron Lowell Palmer

ПРЕДУПРЕЖДЕНИЕ: Есть сообщения, что это не будет работать на 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, не используйте недокументированные функции и все такое. Есть только шесть поддерживаемых типов кнопок, и это не один из них.

37
AndrewS

enter image description here

Прежде всего вы должны найти изображение кнопки "Назад". Я использовал приложение Nice под названием 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];
36
Alexey

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

18
Adam Rosenfield

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

Стандарт:

Standard system back arrow

Apple SD Готический Нео

Apple SD Gothic Neo < character

В Xcode:

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

Ссылка ответ @ staticVoidMan на стрелку "Назад" в iOS 7

14
Bjørn Egil

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

8
machoota
    self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

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

7
quantumpotato

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

// 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;
4
Steve

В библиотеке 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
Andrew Arrow

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

// 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];
4
maralbjo

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

4
Louis Gerbarg

Это легко сделать с помощью Interface Builder в Xcode 5.x

Result

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

    Components

  • в инспекторе атрибутов кнопки edit Image с вашим изображение кнопки назад

    Attributes inspector

Готово!

4
Anton Gaenko

Я пытался сделать то же самое, но я хотел, чтобы кнопка "Назад" была в навигационной панели. (На самом деле мне нужна была кнопка "Назад", которая делала бы больше, чем просто возвращался назад, поэтому мне пришлось использовать свойство 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]];
2
marikaner

Чтобы создать изображение для панели инструментов UIToolbar, создайте png в фотошопе, и ГДЕ там, где есть ЛЮБОЙ цвет, он помещает его в белый цвет, а где он равен альфа = 0, то оставляет его в покое.

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

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

http://twitpic.com/1oanv

и вот как он появился в Интерфейсном Разработчике

http://twitpic.com/1oaoa

1
Domness

Решение без использования PNG. Основываясь на этом ответе SO: Добавление маленькой стрелки в правую часть ячейки в ячейке iPhone TableView

Просто переверните 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];
1
Gabriel Jensen

Пример в 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]
0
Bart van Kuik

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

0
Ben Gottlieb

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
0
user7587085

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

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

0
Shuo

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

0
John Lane