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


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

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

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

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

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

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

23 283

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

Я думаю, что гораздо проще просто использовать символ Юникода, чтобы выполнить эту работу. Вы можете посмотреть через стрелки, погуглив либо Треугольники Юникод или Стрелки Юникод. Начиная с 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} / System/Library/Frameworks / 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];

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

Это легко сделать с Interface Builder на Xcode 5.x

Result

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

    Components

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

    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. Это может, конечно, остановить ваше заявление от утверждения... / Джон

Ну, вы не должны иметь другую кнопку для каждого размера, вы можете использовать [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:

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

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