ios - how - xcode 9 navigation controller




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

O método Unicode

Eu acho que é muito mais fácil usar apenas um caractere unicode para fazer o trabalho. Você pode olhar através de setas pesquisando os Triângulos Unicode ou as Setas Unicode . A partir do iOS6, a Apple alterou o caractere para ser um caractere emoji com uma borda. Para desabilitar a borda, eu adiciono o Seletor de Variação Unicode 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;

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

Para obter uma lista completa de caracteres, pesquise no Google por caracteres Unicode e o que você deseja. Aqui está a entrada para o Triângulo Negro à Esquerda .

Resultado

Eu adoraria criar um botão de seta para a esquerda "de volta" em um UIToolbar .

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

Eu poderia criá-lo manualmente com imagens de botão, mas não consigo encontrar as imagens de origem em nenhum lugar. Eles têm bordas do canal alfa, portanto, a captura de tela e o corte não obtêm resultados muito versáteis.

Alguma idéia além da captura de tela para cada tamanho e esquema de cores que pretendo usar?

Atualização: POR FAVOR, PARE de evitar a pergunta e sugerir que eu não deveria estar perguntando isso e deveria estar usando o 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 desejo colocar um botão Voltar em forma de seta para a esquerda na parte inferior.

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


É fácil fazer com o Interface Builder no Xcode 5.x

  • usar barra de ferramentas e item de botão de barra da biblioteca de objetos

  • na seção do inspetor dos atributos do botão da edição da imagem com sua imagem traseira da tecla

Feito!


Aqui está o que acabei fazendo depois de pesquisar todas essas soluções e outras. Ele usa um png elástico extraído das imagens do UIKit. Desta forma, você pode definir o texto para o que você quer

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

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


Eu estava tentando fazer a mesma coisa, mas queria que o botão voltar estivesse na barra de navegação. (Eu realmente precisava de um botão de volta, que faria mais do que apenas voltar, então eu tive que usar a propriedade leftBarButtonItem). Eu tentei o que o AndrewS sugeriu, mas na barra de navegação não ficaria do jeito que deveria, já que o UIButton foi meio que convertido em um UIBarButtonItem.

Mas eu encontrei uma maneira de contornar isso. Na verdade, basta colocar um UIView sob o UIButton e definir o customView para o UIBarButtonItem. Aqui está o código, se alguém precisar 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]];

Eu tive um problema semelhante e saí de uma biblioteca PButton . E a amostra é o botão de navegação para trás como o botão, que pode ser usado em qualquer lugar como um botão personalizado.

Algo assim:


Exemplo no Swift 3, com um botão anterior e um próximo 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]

Não tenho certeza se isso funcionaria, mas você poderia tentar criar um UINavigationController com as configurações padrão para criar o botão, localize o botão na hierarquia de removeFromSuperview do controlador de navegação, chame removeFromSuperview nele, destrua o controlador de navegação e adicione o botão botão como uma subvisualização da sua barra de ferramentas. Você também pode precisar retain o botão antes de chamar removeFromSuperview (e depois release lo depois de adicioná-lo como subvisualização da sua barra de ferramentas) para evitar que ele seja desalocado durante o processo.


Para fazer um UIButton com uma seta bem próxima (não sou um designer;) para a seta para trás do sistema iOS 7:

Padrão:

Neo gótico da Apple SD

No Xcode:

  • Concentre-se no campo de valor do título do botão (ou em qualquer outra exibição / controle com conteúdo de texto)
  • Abra Editar -> Caracteres Especiais
  • Selecione o grupo Parênteses e clique duas vezes no caractere '<'
  • Alterar fonte para: Apple SD Gothic Neo, Regular com tamanho desejado (por exemplo, 20)
  • Mude a cor como você gosta

Resposta do @stayVoidMan da Ref @ à seta semelhante ao Back no iOS 7


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

Barras de ferramentas têm um estilo visual específico associado a elas. As Diretrizes de Interface Humana para o estado do iPhone:

Uma barra de ferramentas aparece na borda inferior da tela e contém botões que executam ações relacionadas a objetos na exibição atual.

Em seguida, ele fornece vários exemplos visuais de ícones aproximadamente quadrados sem texto. Gostaria de pedir que você siga o HIG sobre isso.


Se você quiser evitar desenhar você mesmo, você pode usar a classe não documentada: UINavigationButton com estilo 1. Isso pode, obviamente, impedir que seu aplicativo seja aprovado ... / John


Solução sem usar um png. Com base nesta resposta SO: Adicionando a pequena seta para o lado direito de uma célula em uma célula TableView do iPhone

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

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


Se você não quer se preocupar com arquivos de imagem, a forma de seta pode ser desenhada 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);
}

onde a visualização da seta é proporcional a uma largura de 6,0 e uma altura de 10,0


Primeiro de tudo você tem que encontrar uma imagem do botão de volta. Eu usei um aplicativo legal chamado Extractor que extrai todos os gráficos do iPhone. No iOS7 eu consegui recuperar a imagem chamada UINavigationBarBackIndicatorDefault e estava na cor preta, já que eu precisava de uma tonalidade vermelha mudo a cor para vermelho usando o Gimp.

EDITAR:

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

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

Então eu criei uma visão que contém um imageView com essa seta, um rótulo com o texto personalizado e no topo da visão 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{
}

EDITAR:

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

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

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

Funciona para mim. Eu usei isso quando eu tinha mais abas, em seguida, poderia caber na barra de abas, e um controlador de exibição empurrou a partir do "Mais" sobrescrever o leftBarButtonItem em seu viewDidLoad.