Aggiunta di una UILabel a una UIToolbar


97

Sto cercando di aggiungere un'etichetta alla mia barra degli strumenti. Il pulsante funziona alla grande, tuttavia quando aggiungo l'oggetto etichetta, si blocca. Qualche idea?

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

Risposte:


128

Dai un'occhiata a questo

[[UIBarButtonItem alloc] initWithCustomView:yourCustomView];

Essenzialmente ogni elemento deve essere un "pulsante" ma possono essere istanziati con qualsiasi visualizzazione richiesta. Ecco un codice di esempio. Nota, poiché gli altri pulsanti sono in genere sulla barra degli strumenti, gli spaziatori sono posizionati su ciascun lato del pulsante del titolo in modo che rimanga centrato.

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

10
Nota che se scegli di seguire questa rotta devi applicare uno stile appropriato alla tua etichetta (label.backgroundColor = [UIColor clearColor], ecc.). Puoi anche avviare un UIBarButtonItem per lo stile normale che ti darà un aspetto simile
wisequark

So che questo è un post molto vecchio, ma ho una domanda su questa risposta. Una volta fatto, c'è un modo per accedere a titleLabel in un secondo momento per cambiarlo, o è impossibile poiché tutto è stato rilasciato?
Ryan

Ryan, probabilmente l'UILabel esiste ancora - è self.titleLabel. Questo esempio richiede una proprietà dichiarata e sintetizzata per UILabel * titleLabel, ma quel codice non viene mostrato. Se hai accesso all'oggetto (probabilmente un UIViewController) che esegue questo codice, puoi accedere al relativo titleLabel. Ad esempio, potresti aggiungere un metodo sul controller della vista, passare il nuovo titolo che desideri e quindi chiamare [self.titleLabel setText: newTitle].
Steve Liddle

7
Non vorresti aggiungere il secondo spaziatore dopo l'elemento della barra dei pulsanti del titolo?
len

121

Per coloro che utilizzano Interface Builder per il layout del tuo UIToolBar, è anche possibile farlo utilizzando solo Interface Builder.

Per aggiungere un UILabela a UIToolBarè necessario aggiungere un UIViewoggetto generico al tuo UIToolBarin IB trascinando un nuovo UIViewoggetto sul tuo UIToolBar. IBcreerà automaticamente un file UIBarButtonItemche verrà inizializzato con il tuo custom UIView. Quindi aggiungi un UILabela UIViewe modifica UILabelgraficamente in modo che corrisponda al tuo stile preferito. È quindi possibile impostare visivamente i distanziatori fissi e / o variabili come desiderato per posizionarli in modo UILabelappropriato.

È inoltre necessario impostare lo sfondo sia di UILabelche UIViewdi clearColorper fare in modo che venga UIToolBarvisualizzato correttamente sotto UILabel.


2
Bel trucco, non sapevo che puoi farlo in Interface Builder. Grazie mille.
Rafael Bugajewski

C'è un modo per aggiungere un UIButton con un'immagine personalizzata usando quel metodo? Posso aggiungere un UIButton, ma l'immagine non viene visualizzata.
cannyboy

4
Non riesco a farlo funzionare. Quando trascino una UIView sulla barra degli strumenti, finisce per essere posizionata all'interno del controller della vista, non sulla barra degli strumenti. Inoltre, lo facciamo nel controller di navigazione o nel controller di visualizzazione?
guptron

1
Non sembra funzionare. Se ha funzionato una volta tanto tempo fa, non più in XCode 6 ...
Frédéric Adda

1
È necessario aggiornare la risposta per sottolineare che funziona solo con le barre degli strumenti aggiunte manualmente a un controller di visualizzazione; non funziona con la barra degli strumenti aggiunta per te.
James Bush

32

Ho trovato molto utile la risposta di answerBot, ma penso di aver trovato un modo ancora più semplice, in Interface Builder:

  • creare un UIBarButtonItem e aggiungerlo alla barra degli strumenti in Interface Builder

inserisci qui la descrizione dell'immagine

  • Deseleziona "abilitato" per questo BarButtonItem

inserisci qui la descrizione dell'immagine

  • collega questo BarButtonItem a una proprietà nella tua classe (questo è in Swift, ma sarebbe molto simile in Obj-C):

    @IBOutlet private weak var lastUpdateButton: UIBarButtonItem! // Dummy barButtonItem whose customView is lastUpdateLabel
  • aggiungi un'altra proprietà per l'etichetta stessa:

    private var lastUpdateLabel = UILabel(frame: CGRectZero)
  • in viewDidLoad, aggiungi il codice seguente per impostare le proprietà della tua etichetta e aggiungilo come customView del tuo BarButtonItem

    // Dummy button containing the date of last update
    lastUpdateLabel.sizeToFit()
    lastUpdateLabel.backgroundColor = UIColor.clearColor()
    lastUpdateLabel.textAlignment = .Center
    lastUpdateButton.customView = lastUpdateLabel
    
  • Per aggiornare il UILabeltesto:

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

Risultato:

inserisci qui la descrizione dell'immagine

Devi chiamare lastUpdateLabel.sizetoFit()ogni volta che aggiorni il testo dell'etichetta


1
Ho creato un UIBarButtonItem come te, l'ho lasciato abilitato e ho sovrapposto un'etichetta usando il seguente codice: UILabel* label = [[UILabel alloc] init]; label.text = @"Hello"; label.font = [UIFont systemFontOfSize:16]; [label sizeToFit]; self.barItem.customView = label;
Brett Donald

6

Una delle cose per cui sto usando questo trucco è istanziare un UIActivityIndicatorViewin cima al UIToolBar, qualcosa che altrimenti non sarebbe possibile. Per esempio qui ho un UIToolBarcon 2 UIBarButtonItem, a FlexibleSpaceBarButtonIteme poi un altro UIBarButtonItem. Voglio inserire un UIActivityIndicatorViewnello UIToolBartra lo spazio flessibile e il pulsante finale (a destra). Quindi nel mio RootViewControllerfaccio quanto segue,

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

Questo codice perde la memoria allocata per UIBarButtonItem con la visualizzazione dell'indicatore di attività personalizzata. (Inoltre perde la memoria dell'indicatore di attività, ma presumo che venga rilasciato sotto la fine del frammento di codice.
erikprice

3

Dettagli

  • Xcode 10.2.1 (10E1001), Swift 5

Campione completo

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

Risultato

inserisci qui la descrizione dell'immagine


Mi piace, ma cosa succede se ho TableView, scorrerà con questa barra. Come lo risolvo?
Maksim Kniazev

Ciao Maxim, non riesco a capire il tuo problema. Per favore, descrivi il risultato che vuoi ottenere.
Vasily Bodnarchuk

Ok, sto usando UITableViewController e se imposto view.addSubview (toolBar!) E scorro il mio tableview la barra scorrerà con tableView, voglio che abbia una posizione inferiore fissa
Maksim Kniazev

Penso che dovresti usare UIViewController con UITableView (invece UITableViewController) come sottoview.
Vasily Bodnarchuk

Ok spasibo. Ci proverò
Maksim Kniazev

2

Simile al costruttore di interfacce utilizzato da Matt RI. Ma volevo averne 1 UIWebViewall'interno in modo da poter avere del testo in grassetto e altro no (come l'app di posta). Così

  1. Aggiungi invece la visualizzazione web.
  2. Deseleziona opaco
  3. Assicurati che lo sfondo sia di colore chiaro
  4. Collega tutto con IBOutlet
  5. Usa quanto segue htmlper avere uno sfondo trasparente in modo che la barra degli strumenti risulti visibile

Codice:

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

1

Se vuoi aggiungere una vista nella barra degli strumenti puoi provare questo:

[self.navigationController.tabBarController.view addSubview:yourView];

1

Prova questo:

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.barItemviene UIBarButtonItemaggiunto dalla libreria degli oggetti e posizionato tra due spazi flessibili.

un altro modo è rimuovere la [self.barItem setCustom:view]riga e modificare i parametri di label(larghezza) in modo che riempia l'intera barra degli strumenti e impostare l'allineamento al centro e il carattere da soli nel codice,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.