Criando um botão de seta para a esquerda (como o estilo “voltar” do UINavigationBar) em um UIToolbar

StackOverflow https://stackoverflow.com/questions/227078

Pergunta

Eu adoraria criar uma esquerda Seta-moldura botão "voltar" em um UIToolbar.

Tanto quanto eu posso dizer, a única maneira de obter um destes é deixar UINavigationController em configurações padrão e usa um para o item da barra esquerda. Mas não há nenhuma maneira que eu posso encontrar para criar um como um UIBarButtonItem, então eu não posso fazer um em um UIToolbar padrão, mesmo que eles são muito semelhantes aos UINavigationBars.

Eu poderia criar manualmente-lo com imagens de botão, mas não consigo encontrar as imagens de origem em qualquer lugar. Eles têm bordas alfa-canal, de modo screenshotting e corte não terá muito versátil resultados.

Todas as ideias além screenshotting para cada esquema de tamanho e cor que eu pretendo usar?

Update: Por favor, pare esquivando-se a questão e sugerindo que eu não deveria estar perguntando isso e deve estar usando UINavigationBar. Meu aplicativo é Instapaper Pro. Ele mostra apenas uma barra de ferramentas inferior (para economizar espaço e maximizar a área de conteúdo legível), e gostaria de colocar um botão Voltar seta para a esquerda em forma no fundo.

me dizendo que eu não deveria precisar fazer isso não é uma resposta e que certamente não merecem uma recompensa.

Foi útil?

Solução

Eu usei o seguinte psd que eu derivado http://www.teehanlax.com / blog /? p = 447

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

Eu, então, acaba de criar um UIView personalizado que eu uso na propriedade customView do item barra de ferramentas.

funciona bem para mim.


Editar: Como apontado por PrairieHippo , maralbjo descobriram que usando o seguinte, código simples fez o truque (exige no pacote ) deve ser combinada com esta resposta. Então aqui está o código adicional:

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

Outras dicas

O Método Unicode

Eu acho que é muito mais fácil simplesmente usar um caractere unicode para começar o trabalho feito. Você pode olhar através de setas por googling quer Unicode Triângulos ou < a href = "http://www.fileformat.info/info/unicode/block/arrows/list.htm" rel = "nofollow noreferrer"> Unicode Arrows . Começando com iOS6 Apple mudou o personagem para ser um caractere emoji com uma borda. Para desativar a fronteira eu adiciono o 0xFE0E Unicode Variação 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;

O bloco de código é apenas para a demonstração. Ele iria trabalhar em qualquer botão que aceita um NSString.

Para obter uma lista completa de personagens pesquisar no Google por caracteres Unicode eo que você quer. Aqui é a entrada para Preto apontando para a esquerda Triangle .

Resultado

O resultado

AVISO: Há relatos de que isto não vai funcionar no iOS 6. Este poder único trabalho em versões mais antigas do sistema operacional. Evidentemente pelo menos um dev teve seu aplicativo rejeitado por usar este truque (ver comentários). Use por sua conta e risco. Usando uma imagem (ver resposta acima) pode ser uma solução mais segura.

Isto pode ser feito sem adicionar em seus próprios arquivos de imagem usando sekr1t botão tipo 101 para obter a forma correta. Para mim, o truque foi descobrir que eu poderia usar initWithCustomView para criar o BarButtonItem. Eu, pessoalmente, precisava disso para uma barra de navegação dinâmica em vez de uma toolbar, mas eu testei com uma barra de ferramentas e o código é quase o mesmo:

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

Se você está fazendo isso de uma barra de ferramentas que você vai ter que ajustar como você definir os itens, mas isso depende do resto do seu código e eu deixar isso como um exercício para o leitor. :. P Esta amostra trabalhou para mim (compilado & run)

Blah blah, leia o HIG, não use recursos não documentados, e tudo isso. Há apenas seis tipos de botão apoiados e isso não é um deles.

enter descrição da imagem aqui

Primeiro de tudo você tem que encontrar uma imagem do botão de volta. Eu usei um aplicativo agradável chamada Extractor que os extratos de todos os gráficos de iPhone. Em iOS7 eu consegui recuperar a imagem chamada UINavigationBarBackIndicatorDefault e foi na cor preta, uma vez que eu precisava de uma tonalidade vermelha I mudar a cor para vermelho usando Gimp.

EDIT:

Como foi mencionado por btate em seu comentário, não há necessidade de mudar a cor com o editor de imagem. O código a seguir deve fazer o truque:

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

Em seguida, eu criei uma exibição que contém uma imageView com aquela flecha, uma etiqueta com o texto personalizado e em cima da vista Eu tenho um botão com uma ação. Então eu adicionei uma animação simples (desbotamento e tradução).

O código a seguir simula o comportamento do botão voltar incluindo animação.

-(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:

Em vez de adicionar o botão, na minha opinião, a melhor abordagem é a utilização de um reconhecedor de gestos.

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

Eu não tenho certeza se isso iria funcionar, mas você pode tentar criar um UINavigationController com as configurações padrão para criar o botão, encontrar o botão na hierarquia subexibição do controlador de navegação, removeFromSuperview chamada nele, destruir o controlador de navegação e em seguida, adicionar o botão como um subview de sua barra de ferramentas. Você também pode precisar de retain eo botão antes de chamar removeFromSuperview (e, em seguida, release-lo depois de adicioná-lo como subexibição de sua barra de ferramentas) para evitar que seja desalocada durante o processo.

Para fazer uma UIButton com uma seta bem perto (eu não sou um designer;) para o sistema iOS 7 seta para trás:

Padrão:

Sistema padrão seta para trás

Apple SD gótico Neo

Apple SD gótico Neo <caráter

No Xcode:

  • Foco no campo de valor título do botão (ou qualquer outra visão / controle com conteúdo de texto)
  • Abrir Editar -> Caracteres Especiais
  • Selecione o grupo Parênteses e dê um duplo clique no '<' carácter
  • Alterar tipo de letra para: Apple SD gótico Neo, regular com o tamanho desejado (por exemplo 20)
  • Alterar cor que você gosta

de @ staticVoidMan resposta to Back-like seta no iOS 7

 seta para trás

Se você não quer se preocupar com arquivos de imagem, a forma de seta pode ser desenhado em uma subclasse UIView com o seguinte código:

- (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);
}

em que o ponto de vista seta é proporcional a uma largura de 6,0 e uma altura de 10,0

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

Funciona para mim. Eu usei isso quando eu tinha mais guias, em seguida, poderia caber na barra de abas, e um controlador de vista empurrado do "Mais" cancelou o leftBarButtonItem em sua viewDidLoad.

Você pode encontrar as imagens de origem por extraindo-los de Other.artwork em UIKit $ {SDKROOT} /System/Library/Frameworks/UIKit.framework/Other.artwork. A comunidade modding tem algumas ferramentas para extraí-los, aqui . Depois de extrair a imagem você pode escrever algum código para recolori-lo quando necessário, e defini-lo como a imagem do botão. Querendo ou não você pode realmente enviar uma coisa dessas (desde que você está incorporando derivado artwork) pode ser um pouco arriscado, então talvez você queira falar com um advogado.

A biblioteca Three20 tem uma maneira de fazer isso:

  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;

Descobri que usando o seguinte, código simples fez o truque (requer imagem personalizada no pacote):

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

Aqui está o que eu acabei fazendo depois de pesquisar através de todas estas soluções e outros. Ele usa um png elástica é extraído das imagens UIKit. Desta forma, você pode definir o texto ao que quer que você 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;

É fácil de fazer com Interface Builder na Xcode 5.x

Resultado

  • uso Barra de Ferramentas e Barra de Botões item de Biblioteca de objeto

    Componentes

  • no botão de Atributos inspetor editar Imagem com o imagem botão voltar

    Atributos inspetor

Feito!

Eu estava tentando fazer a mesma coisa, mas eu queria o botão voltar para a barra de navegação. (Na verdade, eu precisava de um botão voltar, que faria mais do que única volta vai, então eu tive que usar a propriedade leftBarButtonItem). Eu tentei o que Andrews sugeriu, mas na barra de navegação não ficaria da maneira que deveria, como o UIButton era uma espécie de fundido a um UIBarButtonItem.

Mas eu encontrei uma maneira de contornar isso. Eu realmente só colocar um UIView sob a UIButton e definir o customView para o UIBarButtonItem. Aqui está o código, se alguém precisa dele:

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

Para criar uma imagem para o UIToolbar, fazer um png no photoshop e ONDE NUNCA houver qualquer cor que coloca-lo branco, e onde é alfa = 0, em seguida, deixa-lo sozinho.

O SDK da fronteira em torno do ícone que você fez e voltas realmente colocar do que branco, sem que você precise fazer nada.

Veja, isso é o que eu fiz em Photoshop para o meu botão de avanço (obviamente trocá-lo em torno de botão voltar):

http://twitpic.com/1oanv

e é isso que ele apareceu como na Interface Builder

http://twitpic.com/1oaoa

solução sem usando um png. Com base nesta resposta SO: Adicionando uma pequena seta para o lado direito de uma célula em um celular iPhone TableView

Apenas lançando o UITableViewCell horizontalmente!

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

Se você quer evitar desenhá-lo, você pode usar a classe não documentado: UINavigationButton com estilo 1. Isso poderia, é claro, parar o seu aplicativo seja aprovado ... / John

Bem, você não tem que ter um botão diferente para cada tamanho, você pode usar [UIImage stretchableImageWithLeftCapWidth:topCapHeight:], mas a única coisa que eu encontrei é imagens personalizadas.

Eu tive um problema semelhante, e sai uma biblioteca PButton . Ea amostra é o botão de navegação de volta como botão, que pode ser usado em qualquer lugar apenas como um botão personalizado.

Algo parecido com isto: enter descrição da imagem aqui

Exemplo em Swift 3, com um anterior e um próximo botão no canto superior direito.

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

Tente isto. Tenho certeza que você não precisa de uma imagem de botão de volta para criar um tal.

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

Isso é tudo que você tem que fazer:)

Por que você está fazendo isso? Se você quer algo que se parece com uma barra de navegação, o uso UINavigationBar.

Barras de Ferramentas tem estilo visual específico associado com eles. As Human Interface Guidelines para o Estado iPhone:

A barra de ferramentas aparece na borda inferior da tela e contém botões que executam ações relacionadas aos objetos na vista atual.

Em seguida, ele dá vários exemplos visuais de ícones aproximadamente quadrados com nenhum texto. Exorto-vos a seguir o HIG sobre isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top