Adicionando um UILabel a um UIToolbar

97

Estou tentando adicionar um rótulo à minha barra de ferramentas. O botão funciona muito bem, no entanto, quando adiciono o objeto de rótulo, ele trava. Alguma ideia?

UIBarButtonItem *setDateRangeButton = [[UIBarButtonItem alloc] initWithTitle:@"Set date range"
                                                                       style:UIBarButtonItemStyleBordered
                                                                      target:self
                                                                      action:@selector(setDateRangeClicked:)];

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 20, 20)];
label.text = @"test";

[toolbar setItems:[NSArray arrayWithObjects:setDateRangeButton,label, nil]];

// Add the toolbar as a subview to the navigation controller.
[self.navigationController.view addSubview:toolbar];

// Reload the table view
[self.tableView reloadData];
user8359
fonte

Respostas:

128

Dê uma olhada nisso

[[UIBarButtonItem alloc] initWithCustomView:yourCustomView];

Essencialmente, cada item deve ser um "botão", mas podem ser instanciados com qualquer visualização que você precisar. Aqui está algum código de exemplo. Observe que, como outros botões normalmente estão na barra de ferramentas, os espaçadores são colocados em cada lado do botão de título para que ele permaneça centralizado.

NSMutableArray *items = [[self.toolbar items] mutableCopy];

UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[items addObject:spacer];
[spacer release];

self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0 , 11.0f, self.view.frame.size.width, 21.0f)];
[self.titleLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:18]];
[self.titleLabel setBackgroundColor:[UIColor clearColor]];
[self.titleLabel setTextColor:[UIColor colorWithRed:157.0/255.0 green:157.0/255.0 blue:157.0/255.0 alpha:1.0]];
[self.titleLabel setText:@"Title"];
[self.titleLabel setTextAlignment:NSTextAlignmentCenter];

UIBarButtonItem *spacer2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[items addObject:spacer2];
[spacer2 release];

UIBarButtonItem *title = [[UIBarButtonItem alloc] initWithCustomView:self.titleLabel];
[items addObject:title];
[title release];

[self.toolbar setItems:items animated:YES];
[items release];
resposta
fonte
10
Observe que se você escolheu seguir este caminho, você deve estilizar seu rótulo apropriadamente (label.backgroundColor = [UIColor clearColor], etc). Você também pode inicializar um UIBarButtonItem para ser estilizado como Simples, o que lhe dará uma aparência semelhante
wisequark
Eu sei que este é um post muito antigo, mas tenho uma pergunta sobre essa resposta. Feito isso, há alguma maneira de acessar o titleLabel mais tarde para alterá-lo, ou é impossível já que tudo foi lançado?
Ryan
Ryan, o UILabel provavelmente ainda existe - é self.titleLabel. Este exemplo precisa de uma propriedade declarada e sintetizada para UILabel * titleLabel, mas esse código não é mostrado. Se você tiver acesso ao objeto (provavelmente um UIViewController) que executa este código, poderá acessar seu titleLabel. Por exemplo, você pode adicionar um método no controlador de visualização, passar o novo título desejado e, em seguida, chamar [self.titleLabel setText: newTitle].
Steve Liddle
7
Você não gostaria que o segundo espaçador fosse adicionado após o item da barra de botões de título?
len
121

Para aqueles que usam o Interface Builder para fazer o layout do seu UIToolBar, também é possível fazer isso usando apenas o Interface Builder.

Para adicionar a UILabela a, UIToolBarvocê precisa adicionar um UIViewobjeto genérico ao seu UIToolBarno IB arrastando um novo UIViewobjeto sobre o seu UIToolBar. IBirá criar automaticamente um UIBarButtonItemque será inicializado com seu custom UIView. Em seguida, adicione um UILabelao UIViewe edite-o UILabelgraficamente para corresponder ao seu estilo preferido. Você pode então configurar visualmente seus espaçadores fixos e / ou variáveis ​​conforme desejado para posicionar seuUILabel apropriadamente.

Você também deve definir o plano de fundo de UILabele UIViewde clearColorpara fazer UIToolBarcom que apareça corretamente sob UILabel.

Matt R
fonte
2
Belo truque, não sabia que você pode fazer isso no Interface Builder. Muito obrigado.
Rafael Bugajewski
Existe uma maneira de adicionar um UIButton com imagem personalizada usando esse método? Posso adicionar um UIButton, mas a imagem não aparece.
cannyboy
4
Não consigo fazer isso funcionar. Quando arrasto um UIView para a barra de ferramentas, ele acaba sendo colocado dentro do controlador de visualização, não na barra de ferramentas. Além disso, fazemos isso no controlador de navegação ou no controlador de visualização?
guptron
1
Isso não parece funcionar. Se funcionou uma vez há muito tempo, não mais no XCode 6 ...
Frédéric Adda
1
Você deve atualizar sua resposta para apontar que isso só funciona com barras de ferramentas adicionadas a um controlador de visualização manualmente; não funciona com a barra de ferramentas adicionada para você.
James Bush
32

Achei a resposta do answerBot muito útil, mas acho que encontrei uma maneira ainda mais fácil, no Interface Builder:

  • crie um UIBarButtonItem e adicione-o à sua barra de ferramentas no Interface Builder

insira a descrição da imagem aqui

  • Desmarque "ativado" para este BarButtonItem

insira a descrição da imagem aqui

  • conecte este BarButtonItem a uma propriedade em sua classe (isso está em Swift, mas seria muito semelhante em Obj-C):

    @IBOutlet private weak var lastUpdateButton: UIBarButtonItem! // Dummy barButtonItem whose customView is lastUpdateLabel
  • adicione outra propriedade para o próprio rótulo:

    private var lastUpdateLabel = UILabel(frame: CGRectZero)
  • em viewDidLoad, adicione o seguinte código para definir as propriedades de seu rótulo e adicione-o como customView de seu BarButtonItem

    // Dummy button containing the date of last update
    lastUpdateLabel.sizeToFit()
    lastUpdateLabel.backgroundColor = UIColor.clearColor()
    lastUpdateLabel.textAlignment = .Center
    lastUpdateButton.customView = lastUpdateLabel
  • Para atualizar o UILabel texto:

    lastUpdateLabel.text = "Updated: 9/12/14, 2:53"
    lastUpdateLabel.sizeToFit() 

Resultado:

insira a descrição da imagem aqui

Você deve ligar lastUpdateLabel.sizetoFit()sempre que atualizar o texto do rótulo

Frederic Adda
fonte
1
Criei um UIBarButtonItem igual ao seu, deixei-o ativado e sobrepus um rótulo usando o seguinte código: UILabel* label = [[UILabel alloc] init]; label.text = @"Hello"; label.font = [UIFont systemFontOfSize:16]; [label sizeToFit]; self.barItem.customView = label;
Brett Donald
6

Uma das coisas para que estou usando esse truque é instanciar um UIActivityIndicatorViewno topo de UIToolBar, algo que de outra forma não seria possível. Por exemplo, aqui eu tenho um UIToolBarcom 2 UIBarButtonItem, um FlexibleSpaceBarButtonIteme depois outro UIBarButtonItem. Eu quero inserir um UIActivityIndicatorViewnoUIToolBar entre o espaço flexível e o botão final (do lado direito). Então, no meu, RootViewControllereu faço o seguinte,

- (void)viewDidLoad {
[super viewDidLoad];// Add an invisible UIActivityViewIndicator to the toolbar
UIToolbar *toolbar = (UIToolbar *)[self.view viewWithTag:767];
NSArray *items = [toolbar items];

activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 20.0f, 20.0f)];
[activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhite];    

NSArray *newItems = [NSArray arrayWithObjects:[items objectAtIndex:0],[items objectAtIndex:1],[items objectAtIndex:2],
                     [[UIBarButtonItem alloc] initWithCustomView:activityIndicator], [items objectAtIndex:3],nil];
[toolbar setItems:newItems];}
Alasdair Allan
fonte
Este código vaza a memória alocada para o UIBarButtonItem com a visualização do indicador de atividade customizada. (Ele também vaza a memória do indicador de atividade, mas presumo que esteja sendo lançado abaixo do final do fragmento de código.
erikprice
3

Detalhes

  • Xcode 10.2.1 (10E1001), Swift 5

Amostra completa

import UIKit

class ViewController: UIViewController {

    private weak var toolBar: UIToolbar?

    override func viewDidLoad() {
        super.viewDidLoad()

        var bounds =  UIScreen.main.bounds
        let bottomBarWithHeight = CGFloat(44)
        bounds.origin.y = bounds.height - bottomBarWithHeight
        bounds.size.height = bottomBarWithHeight
        let toolBar = UIToolbar(frame: bounds)
        view.addSubview(toolBar)

        var buttons = [UIBarButtonItem]()
        buttons.append(UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(ViewController.action)))
        buttons.append(UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(ViewController.action)))
        buttons.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil))
        buttons.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil))
        buttons.append(ToolBarTitleItem(text: "\(NSDate())", font: .systemFont(ofSize: 12), color: .lightGray))
        buttons.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil))
        buttons.append(UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action:  #selector(ViewController.action)))
        toolBar.items = buttons

        self.toolBar = toolBar
    }
    @objc func action() { print("action") }
}

class ToolBarTitleItem: UIBarButtonItem {

    init(text: String, font: UIFont, color: UIColor) {
        let label =  UILabel(frame: UIScreen.main.bounds)
        label.text = text
        label.sizeToFit()
        label.font = font
        label.textColor = color
        label.textAlignment = .center
        super.init()
        customView = label
    }
    required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
}

Resultado

insira a descrição da imagem aqui

Vasily Bodnarchuk
fonte
Eu gosto disso, mas e se eu tiver o TableView, ele irá rolar com esta barra. Como faço para corrigir isso?
Maksim Kniazev,
Olá Maxim, não consigo entender o seu problema. Por favor, descreva o resultado que deseja obter.
Vasily Bodnarchuk,
Ok, estou usando UITableViewController e se eu definir view.addSubview (toolBar!) E rolar meu tableview, a barra rolará com tableView, quero que tenha uma posição inferior fixa
Maksim Kniazev
Eu acho que você deve usar UIViewController com UITableView (em vez de UITableViewController) como uma subvisualização.
Vasily Bodnarchuk,
Ok spasibo. Vou tentar isso
Maksim Kniazev
2

Semelhante ao construtor de interface usado Matt RI. Mas eu queria ter um UIWebViewdentro, para que eu pudesse ter algum texto em negrito e outro não (como o aplicativo de e-mail). assim

  1. Em vez disso, adicione a visualização da web.
  2. Desmarque opaco
  3. Certifique-se de que o fundo seja de cor clara
  4. Conecte tudo com IBOutlet
  5. Use o seguinte htmlpara ter um fundo transparente para que a barra de ferramentas brilhe

Código:

NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
NSString *html = [NSString stringWithFormat:@"<html><head><style>body{font-size:11px;text-align:center;background-color:transparent;color:#fff;font-family:helvetica;vertical-align:middle;</style> </head><body><b>Updated</b> 10/11/12 <b>11:09</b> AM</body></html>"];
[myWebView loadHTMLString:html baseURL:baseURL];
Todd Horst
fonte
1

Se você deseja adicionar uma visualização na visualização da barra de ferramentas, você pode tentar o seguinte:

[self.navigationController.tabBarController.view addSubview:yourView];
mrhevor
fonte
1

Experimente isto:

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(140 , 0, 50, 250)];
[label setBackgroundColor:[UIColor clearColor]];
label.text = @"TEXT";
UIView *view = (UIView *) label;
[self.barItem setCustomView:view];

Nota: self.barItemé umUIBarButtonItem adicionado da biblioteca de objetos e colocado entre dois espaços flexíveis.

outra forma é remover a [self.barItem setCustom:view]linha e alterar os parâmetros de label(largura) para que preencha toda a barra de ferramentas e definir o alinhamento para o meio e a fonte por você no código,

usuário 1938695
fonte