Ajout d'un UILabel à une UIToolbar

97

J'essaye d'ajouter une étiquette à ma barre d'outils. Le bouton fonctionne très bien, mais lorsque j'ajoute l'objet étiquette, il se bloque. Des idées?

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
la source

Réponses:

128

Jetez un œil à ceci

[[UIBarButtonItem alloc] initWithCustomView:yourCustomView];

Essentiellement, chaque élément doit être un "bouton", mais ils peuvent être instanciés avec n'importe quelle vue dont vous avez besoin. Voici un exemple de code. Notez que, comme les autres boutons se trouvent généralement dans la barre d'outils, des entretoises sont placées de chaque côté du bouton de titre afin qu'il reste centré.

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
la source
10
Notez que si vous avez choisi cette voie, vous devez styliser votre étiquette de manière appropriée (label.backgroundColor = [UIColor clearColor], etc.). Vous pouvez également lancer un UIBarButtonItem pour qu'il soit stylé Plain qui vous donnera un look similaire
wisequark
Je sais que c'est un très vieux post, mais j'ai une question à propos de cette réponse. Une fois que cela est fait, y a-t-il un moyen d'accéder au titleLabel plus tard pour le changer, ou est-ce impossible puisque tout a été publié?
Ryan
Ryan, l'UILabel existe probablement toujours - c'est self.titleLabel. Cet exemple nécessite une propriété déclarée et synthétisée pour UILabel * titleLabel, mais ce code n'est pas affiché. Si vous avez accès à l'objet (probablement un UIViewController) qui exécute ce code, vous pouvez accéder à son titleLabel. Par exemple, vous pouvez ajouter une méthode sur le contrôleur de vue, passer le nouveau titre souhaité, puis appeler [self.titleLabel setText: newTitle].
Steve Liddle
7
Ne voudriez-vous pas que le deuxième espaceur soit ajouté après l'élément de la barre de boutons de titre?
len
121

Pour ceux qui utilisent Interface Builder pour mettre en page votre UIToolBar, il est également possible de le faire en utilisant Interface Builder seul.

Pour ajouter un UILabelà un, UIToolBarvous devez ajouter un UIViewobjet générique à votre UIToolBardans IB en faisant glisser un nouvel UIViewobjet sur votre UIToolBar. IBcréera automatiquement un UIBarButtonItemqui sera initialisé avec votre custom UIView. Ajoutez ensuite un UILabelà UIViewet modifiez-le UILabelgraphiquement pour correspondre à votre style préféré. Vous pouvez ensuite configurer visuellement vos entretoises fixes et / ou variables comme vous le souhaitez pour les positionner de UILabelmanière appropriée.

Vous devez également définir l'arrière-plan du UILabelet du UIViewà clearColorpour que le UIToolBars'affiche correctement sous le UILabel.

Matt R
la source
2
Belle astuce, je ne savais pas que vous pouviez le faire dans Interface Builder. Merci beaucoup.
Rafael Bugajewski
Existe-t-il un moyen d'ajouter un UIButton avec une image personnalisée à l'aide de cette méthode? Je peux ajouter un UIButton, mais l'image ne s'affiche pas.
cannyboy
4
Je n'arrive pas à faire fonctionner ça. Lorsque je fais glisser un UIView sur la barre d'outils, il finit par être placé à l'intérieur du contrôleur de vue, pas dans la barre d'outils. Aussi, faisons-nous cela dans le contrôleur de navigation ou dans le contrôleur de vue?
guptron
1
Cela ne semble pas fonctionner. Si ça marchait il y a longtemps, plus en XCode 6 ...
Frédéric Adda
1
Vous devez mettre à jour votre réponse pour souligner que cela ne fonctionne qu'avec les barres d'outils ajoutées manuellement à un contrôleur de vue; cela ne fonctionne pas avec la barre d'outils qui est ajoutée pour vous.
James Bush
32

J'ai trouvé la réponse de answerBot très utile, mais je pense avoir trouvé un moyen encore plus simple, dans Interface Builder:

  • créer un UIBarButtonItem et l'ajouter à votre barre d'outils dans Interface Builder

entrez la description de l'image ici

  • Décochez "activé" pour cet élément BarButtonItem

entrez la description de l'image ici

  • branchez ce BarButtonItem à une propriété de votre classe (c'est dans Swift, mais serait très similaire dans Obj-C):

    @IBOutlet private weak var lastUpdateButton: UIBarButtonItem! // Dummy barButtonItem whose customView is lastUpdateLabel
  • ajoutez une autre propriété pour l'étiquette elle-même:

    private var lastUpdateLabel = UILabel(frame: CGRectZero)
  • dans viewDidLoad, ajoutez le code suivant pour définir les propriétés de votre étiquette et ajoutez-le en tant que customView de votre BarButtonItem

    // Dummy button containing the date of last update
    lastUpdateLabel.sizeToFit()
    lastUpdateLabel.backgroundColor = UIColor.clearColor()
    lastUpdateLabel.textAlignment = .Center
    lastUpdateButton.customView = lastUpdateLabel
    
  • Pour mettre à jour le UILabeltexte:

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

Résultat :

entrez la description de l'image ici

Vous devez appeler lastUpdateLabel.sizetoFit()chaque fois que vous mettez à jour le texte de l'étiquette

Frederic Adda
la source
1
J'ai créé un UIBarButtonItem identique à vous, je l'ai laissé activé et j'ai superposé une étiquette en utilisant le code suivant: UILabel* label = [[UILabel alloc] init]; label.text = @"Hello"; label.font = [UIFont systemFontOfSize:16]; [label sizeToFit]; self.barItem.customView = label;
Brett Donald
6

Une des choses pour lesquelles j'utilise cette astuce est d'instancier un UIActivityIndicatorViewpar-dessus UIToolBar, quelque chose qui autrement ne serait pas possible. Par exemple ici, j'ai un UIToolBaravec 2 UIBarButtonItem, un FlexibleSpaceBarButtonItem, puis un autre UIBarButtonItem. Je veux insérer un UIActivityIndicatorViewdans l' UIToolBarentre l'espace flexible et le dernier bouton ( à droite). Donc dans mon RootViewControllerje fais ce qui suit,

- (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
la source
Ce code perd la mémoire allouée à UIBarButtonItem avec la vue d'indicateur d'activité personnalisée. (Il fuit également la mémoire de l'indicateur d'activité, mais je suppose qu'il est publié en dessous de la fin du fragment de code.
erikprice
3

Détails

  • Xcode 10.2.1 (10E1001), Swift 5

Échantillon complet

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

Résultat

entrez la description de l'image ici

Vasily Bodnarchuk
la source
J'aime ça, mais si j'ai TableView, il défilera avec cette barre. Comment résoudre ce problème?
Maksim Kniazev
Bonjour Maxim, je ne comprends pas votre problème. Veuillez décrire le résultat que vous souhaitez obtenir.
Vasily Bodnarchuk
Ok, j'utilise UITableViewController et si je définis view.addSubview (toolBar!) Et que je fais défiler ma tableview, la barre défilera avec tableView, je veux qu'elle ait une position inférieure fixe
Maksim Kniazev
Je pense que vous devriez utiliser UIViewController avec UITableView (au lieu de UITableViewController) comme sous-vue.
Vasily Bodnarchuk
Ok spasibo. Je vais essayer ça
Maksim Kniazev
2

Semblable à Matt RI utilisé le constructeur d'interface. Mais je voulais en avoir 1 UIWebViewà la place afin que je puisse avoir du texte en gras et d'autres pas du texte (comme l'application de messagerie). Alors

  1. Ajoutez plutôt la vue Web.
  2. Décocher opaque
  3. Assurez-vous que l'arrière-plan est de couleur claire
  4. Accrochez tout avec IBOutlet
  5. Utilisez ce qui suit htmlpour avoir un arrière-plan transparent afin que la barre d'outils brille à travers

Code:

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
la source
1

Si vous souhaitez ajouter une vue dans la vue de la barre d'outils, vous pouvez essayer ceci:

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

Essaye ça:

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

Remarque: self.barItemest un UIBarButtonItemajout de la bibliothèque d'objets et placé entre deux espaces flexibles.

une autre façon est de supprimer la [self.barItem setCustom:view]ligne et de modifier les paramètres de la label(largeur) afin qu'elle remplisse toute la barre d'outils et de définir l'alignement au milieu et la police par vous-même dans le code,

user1938695
la source