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

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

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

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

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

обновление: пожалуйста, перестаньте уклоняться от вопроса и предполагать, что я не должен задавать это и должен использовать UINavigationBar. Мое приложение-Instapaper Pro. Он показывает только нижнюю панель инструментов (чтобы сэкономить место и максимизировать читаемую область содержимого), и я хочу поставить левую стрелку назад кнопка внизу.

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

23 ответов


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

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

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

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


Edit: как указал 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];

Метод Unicode

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


предупреждение: есть информация, что это не будет работать на iOS 6. Это может работать только на более старых версиях ОС. Очевидно, по крайней мере, один dev отказался от своего приложения за использование этого трюка (см. комментарии). Используйте на свой страх и риск. Использование изображения (см. ответ выше) может быть более безопасным решением.

Это можно сделать без добавления собственных файлов изображений с помощью кнопки sekr1t тип 101, чтобы получить правильную форму. Для меня хитрость заключалась в том, чтобы понять, что я могу использовать. initWithCustomView создать BarButtonItem. Мне лично это было нужно для динамического navbar, а не 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 этот образец работал для меня (compiled & run).

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


enter image description here

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

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


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

стандартные:

Standard system back arrow

Apple SD Gothic Neo

Apple SD Gothic Neo < character

В Xcode:

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

Ref @staticVoidMan это!--28--> назад-как стрелка на iOS 7


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


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

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


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


библиотека 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;

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

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

вот что я сделал после поиска всех этих решений и других. Он использует растягивающийся 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;

Это легко сделать с Интерфейс Построителя на Xcode 5.x

Result

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

    Components

  • в кнопки атрибуты инспектора редактировать изображения с код обратно изображение

    Attributes inspector

готово!


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

чтобы создать изображение для UIToolbar, сделайте png в photoshop, и где бы ни был какой-либо цвет, он помещает его в белый цвет, а где Альфа = 0, тогда он оставляет его в покое.

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

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

http://twitpic.com/1oanv

и это то, что он появился в Interface Builder

http://twitpic.com/1oaoa


решение без использования png. Исходя из этого так ответ:добавление маленькой стрелки в правую часть ячейки в ячейке 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];

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


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


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

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


пример в 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]

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

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

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

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


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

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

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

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