Agregar un UILabel a un UIToolbar

97

Estoy intentando agregar una etiqueta a mi barra de herramientas. El botón funciona muy bien, sin embargo, cuando agrego el objeto de etiqueta, se bloquea. ¿Algunas ideas?

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

Respuestas:

128

Echa un vistazo a esto

[[UIBarButtonItem alloc] initWithCustomView:yourCustomView];

Básicamente, cada elemento debe ser un "botón", pero se pueden crear instancias con cualquier vista que necesite. Aquí hay un código de ejemplo. Tenga en cuenta que, dado que otros botones suelen estar en la barra de herramientas, los espaciadores se colocan a cada lado del botón de título para que permanezca centrado.

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];
Answerbot
fuente
10
Tenga en cuenta que si elige seguir esta ruta, debe diseñar su etiqueta de manera adecuada (label.backgroundColor = [UIColor clearColor], etc.). También puede iniciar un UIBarButtonItem para que tenga un estilo simple, lo que le dará un aspecto similar
Wisequark
Sé que esta es una publicación realmente antigua, pero tengo una pregunta sobre esta respuesta. Una vez hecho esto, ¿hay alguna forma de acceder al titleLabel más tarde para cambiarlo, o es imposible ya que todo ha sido lanzado?
Ryan
Ryan, el UILabel probablemente todavía existe, es self.titleLabel. Este ejemplo necesita una propiedad declarada y sintetizada para UILabel * titleLabel, pero ese código no se muestra. Si tiene acceso al objeto (probablemente un UIViewController) que ejecuta este código, puede acceder a su titleLabel. Por ejemplo, puede agregar un método en el controlador de vista, pasar el nuevo título que desee y luego llamar a [self.titleLabel setText: newTitle].
Steve Liddle
7
¿No le gustaría agregar el segundo espaciador después del elemento de la barra de botones de título?
len
121

Para aquellos que usan Interface Builder para diseñar su UIToolBar, también es posible hacerlo usando solo Interface Builder.

Para agregar un UILabela UIToolBar, debe agregar un UIViewobjeto genérico a su UIToolBaren IB arrastrando un nuevo UIViewobjeto sobre su UIToolBar. IBcreará automáticamente un archivo UIBarButtonItemque se inicializará con su archivo personalizado UIView. A continuación añadimos una UILabela la UIViewy editar la UILabelgráfica para que coincida con su estilo preferido. A continuación, puede configurar visualmente sus espaciadores fijos y / o variables como desee para colocarlos UILabelcorrectamente.

También debe establecer el fondo de UILabely de UIViewpara clearColorque se UIToolBarmuestre correctamente debajo de UILabel.

Matt R
fuente
2
Buen truco, no sabía que podía hacerlo en Interface Builder. Muchas gracias.
Rafael Bugajewski
¿Hay alguna forma de agregar un UIButton con una imagen personalizada usando ese método? Puedo agregar un UIButton, pero la imagen no aparece.
cannyboy
4
Parece que no puedo hacer que esto funcione. Cuando arrastro una UIView a la barra de herramientas, termina colocándose dentro del controlador de vista, no en la barra de herramientas. Además, ¿hacemos esto en el controlador de navegación o en el controlador de vista?
guptron
1
Eso no parece funcionar. Si funcionó una vez hace mucho tiempo, ya no en XCode 6 ...
Frédéric Adda
1
Debe actualizar su respuesta para señalar que esto solo funciona con barras de herramientas agregadas a un controlador de vista manualmente; no funciona con la barra de herramientas que se agregó automáticamente.
James Bush
32

Encontré la respuesta de answerBot muy útil, pero creo que encontré una forma aún más fácil, en Interface Builder:

  • cree un UIBarButtonItem y agréguelo a su barra de herramientas en Interface Builder

ingrese la descripción de la imagen aquí

  • Desmarque "habilitado" para este BarButtonItem

ingrese la descripción de la imagen aquí

  • conecte este BarButtonItem a una propiedad en su clase (esto está en Swift, pero sería muy similar en Obj-C):

    @IBOutlet private weak var lastUpdateButton: UIBarButtonItem! // Dummy barButtonItem whose customView is lastUpdateLabel
  • agregue otra propiedad para la etiqueta en sí:

    private var lastUpdateLabel = UILabel(frame: CGRectZero)
  • en viewDidLoad, agregue el siguiente código para establecer las propiedades de su etiqueta y agréguelo como customView de su BarButtonItem

    // Dummy button containing the date of last update
    lastUpdateLabel.sizeToFit()
    lastUpdateLabel.backgroundColor = UIColor.clearColor()
    lastUpdateLabel.textAlignment = .Center
    lastUpdateButton.customView = lastUpdateLabel
  • Para actualizar el UILabeltexto:

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

Resultado:

ingrese la descripción de la imagen aquí

Tienes que llamar lastUpdateLabel.sizetoFit()cada vez que actualices el texto de la etiqueta.

Frederic Adda
fuente
1
Creé un UIBarButtonItem igual que usted, lo dejé habilitado y superpuse una etiqueta con el siguiente código: UILabel* label = [[UILabel alloc] init]; label.text = @"Hello"; label.font = [UIFont systemFontOfSize:16]; [label sizeToFit]; self.barItem.customView = label;
Brett Donald
6

Una de las cosas para las que estoy usando este truco es para crear una instancia UIActivityIndicatorViewsobre el UIToolBar, algo que de otra manera no sería posible. Por ejemplo, aquí tengo a UIToolBarcon 2 UIBarButtonItem, a FlexibleSpaceBarButtonItem, y luego otro UIBarButtonItem. Quiero insertar un UIActivityIndicatorViewen UIToolBarentre el espacio flexible y el botón final (de la derecha). Entonces en mi RootViewControllerhago lo siguiente,

- (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
fuente
Este código pierde la memoria asignada para UIBarButtonItem con la vista de indicador de actividad personalizada. (También filtra la memoria del indicador de actividad, pero supongo que se publicará debajo del final del fragmento de código.
erikprice
3

Detalles

  • Xcode 10.2.1 (10E1001), Swift 5

Muestra 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

ingrese la descripción de la imagen aquí

Vasily Bodnarchuk
fuente
Me gusta esto, pero ¿qué pasa si tengo TableView, luego se desplazará con esta barra? ¿Cómo arreglo eso?
Maksim Kniazev
Hola Maxim, no puedo entender tu problema. Por favor, describa el resultado que desea obtener.
Vasily Bodnarchuk
Ok, estoy usando UITableViewController y si configuro view.addSubview (toolBar!) Y desplazo mi vista de tabla, la barra se desplazará con tableView, quiero que tenga una posición inferior fija
Maksim Kniazev
Creo que debería usar UIViewController con UITableView (en lugar de UITableViewController) como una subvista.
Vasily Bodnarchuk
Ok spasibo. Lo intentaré
Maksim Kniazev
2

Similar al constructor de interfaces usado por Matt RI. Pero quería tener 1 UIWebViewadentro en su lugar para poder tener un texto en negrita y otro texto no (como la aplicación de correo). Entonces

  1. En su lugar, agregue la vista web.
  2. Desmarque opaco
  3. Asegúrese de que el fondo sea de color claro
  4. Conecta todo con IBOutlet
  5. Use lo siguiente htmlpara tener un fondo transparente para que la barra de herramientas brille a través

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
fuente
1

Si desea agregar una vista a la vista de la barra de herramientas, puede intentar esto:

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

Prueba esto:

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.barItemes un UIBarButtonItemagregado de la biblioteca de objetos y se coloca entre dos espacios flexibles.

otra forma es eliminar la [self.barItem setCustom:view]línea y cambiar los parámetros del label(ancho) para que llene toda la barra de herramientas y establecer la alineación en el medio y la fuente usted mismo en el código,

usuario 1938695
fuente