Hinzufügen eines UILabels zu einer UIToolbar


97

Ich versuche, meiner Symbolleiste eine Beschriftung hinzuzufügen. Die Schaltfläche funktioniert hervorragend, aber wenn ich das Beschriftungsobjekt hinzufüge, stürzt es ab. Irgendwelche Ideen?

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

Antworten:


128

Schauen Sie sich das an

[[UIBarButtonItem alloc] initWithCustomView:yourCustomView];

Grundsätzlich muss jedes Element eine "Schaltfläche" sein, aber sie können mit jeder gewünschten Ansicht instanziiert werden. Hier ist ein Beispielcode. Da sich normalerweise andere Schaltflächen in der Symbolleiste befinden, werden Abstandhalter auf jeder Seite der Titelschaltfläche platziert, damit sie zentriert bleibt.

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
Beachten Sie, dass Sie Ihr Etikett entsprechend formatieren müssen, wenn Sie sich für diese Route entschieden haben (label.backgroundColor = [UIColor clearColor] usw.). Sie können auch ein UIBarButtonItem für Plain erstellen, das Ihnen ein ähnliches Aussehen
verleiht

Ich weiß, dass dies ein wirklich alter Beitrag ist, aber ich habe eine Frage zu dieser Antwort. Gibt es eine Möglichkeit, später auf das titleLabel zuzugreifen, um es zu ändern, oder ist es unmöglich, da alles veröffentlicht wurde?
Ryan

Ryan, das UILabel existiert wahrscheinlich noch - es ist self.titleLabel. In diesem Beispiel muss eine Eigenschaft für UILabel * titleLabel deklariert und synthetisiert werden, dieser Code wird jedoch nicht angezeigt. Wenn Sie Zugriff auf das Objekt (wahrscheinlich einen UIViewController) haben, auf dem dieser Code ausgeführt wird, können Sie auf sein titleLabel zugreifen. Sie können beispielsweise eine Methode auf dem Ansichts-Controller hinzufügen, den gewünschten neuen Titel übergeben und dann [self.titleLabel setText: newTitle] aufrufen.
Steve Liddle

7
Möchten Sie nicht, dass der zweite Abstandhalter nach dem Element der Titeltastenleiste hinzugefügt wird?
Len

121

Für diejenigen, die Interface Builder zum Layouten verwenden UIToolBar, ist es auch möglich, dies nur mit Interface Builder zu tun.

Um ein UILabelzu einem hinzuzufügen , müssen UIToolBarSie UIViewIhrem UIToolBarin IB ein generisches Objekt hinzufügen, indem Sie ein neues UIViewObjekt über Ihr ziehen UIToolBar. IBerstellt automatisch eine UIBarButtonItem, die mit Ihrer benutzerdefinierten initialisiert wird UIView. Als nächstes fügen Sie ein UILabelzum UIViewund bearbeiten die UILabelgrafisch Ihren bevorzugten Stil anzupassen. Sie können dann Ihre festen und / oder variablen Abstandshalter nach Bedarf visuell einrichten, um sie UILabelentsprechend zu positionieren .

Außerdem müssen Sie den Hintergrund der beiden UILabelund die UIViewan und clearColorrufen Sie die UIToolBarrichtig unter die durch zu zeigen UILabel.


2
Netter Trick, wusste nicht, dass Sie es in Interface Builder tun können. Vielen Dank.
Rafael Bugajewski

Gibt es eine Möglichkeit, mit dieser Methode einen UIButton mit benutzerdefiniertem Bild hinzuzufügen? Ich kann einen UIButton hinzufügen, aber das Bild wird nicht angezeigt.
Cannyboy

4
Ich kann das scheinbar nicht zum Laufen bringen. Wenn ich eine UIView auf die Symbolleiste ziehe, wird sie im View Controller und nicht in der Symbolleiste platziert. Tun wir dies auch im Navigationscontroller oder im Ansichtscontroller?
Guptron

1
Das scheint nicht zu funktionieren. Wenn es vor langer Zeit einmal funktioniert hat, nicht mehr in XCode 6 ...
Frédéric Adda

1
Sie sollten Ihre Antwort aktualisieren, um darauf hinzuweisen, dass dies nur mit Symbolleisten funktioniert, die manuell zu einem Ansichtscontroller hinzugefügt wurden. Es funktioniert nicht mit der Symbolleiste, die für Sie hinzugefügt wurde.
James Bush

32

Ich fand die Antwort von answerBot sehr nützlich, aber ich denke, ich habe in Interface Builder einen noch einfacheren Weg gefunden:

  • Erstellen Sie ein UIBarButtonItem und fügen Sie es Ihrer Symbolleiste im Interface Builder hinzu

Geben Sie hier die Bildbeschreibung ein

  • Deaktivieren Sie "aktiviert" für dieses BarButtonItem

Geben Sie hier die Bildbeschreibung ein

  • Stecken Sie dieses BarButtonItem in eine Eigenschaft in Ihrer Klasse (dies ist in Swift, wäre aber in Obj-C sehr ähnlich):

    @IBOutlet private weak var lastUpdateButton: UIBarButtonItem! // Dummy barButtonItem whose customView is lastUpdateLabel
  • Fügen Sie eine weitere Eigenschaft für das Label selbst hinzu:

    private var lastUpdateLabel = UILabel(frame: CGRectZero)
  • Fügen Sie in viewDidLoad den folgenden Code hinzu, um die Eigenschaften Ihres Etiketts festzulegen, und fügen Sie ihn als benutzerdefinierte Ansicht Ihres BarButtonItem hinzu

    // Dummy button containing the date of last update
    lastUpdateLabel.sizeToFit()
    lastUpdateLabel.backgroundColor = UIColor.clearColor()
    lastUpdateLabel.textAlignment = .Center
    lastUpdateButton.customView = lastUpdateLabel
    
  • So aktualisieren Sie den UILabelText:

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

Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Sie müssen lastUpdateLabel.sizetoFit()jedes Mal aufrufen, wenn Sie den Beschriftungstext aktualisieren


1
Ich habe ein UIBarButtonItem wie Sie erstellt, es aktiviert gelassen und ein Label mit dem folgenden Code überlagert: UILabel* label = [[UILabel alloc] init]; label.text = @"Hello"; label.font = [UIFont systemFontOfSize:16]; [label sizeToFit]; self.barItem.customView = label;
Brett Donald

6

Eines der Dinge, für die ich diesen Trick verwende, ist das Instanziieren eines UIActivityIndicatorViewdarüber UIToolBar, etwas, das sonst nicht möglich wäre. Zum Beispiel habe ich hier eine UIToolBarmit 2 UIBarButtonItem, eine FlexibleSpaceBarButtonItemund dann eine andere UIBarButtonItem. Ich möchte einen UIActivityIndicatorViewin den UIToolBarzwischen dem flexiblen Raum und dem letzten (rechten) Knopf einfügen . Also RootViewControllermache ich in meinem folgenden:

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

Dieser Code verliert den für das UIBarButtonItem mit der benutzerdefinierten Aktivitätsindikatoransicht zugewiesenen Speicher. (Es verliert auch den Speicher des Aktivitätsindikators, aber ich
gehe

3

Einzelheiten

  • Xcode 10.2.1 (10E1001), Swift 5

Vollständige Probe

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

Ergebnis

Geben Sie hier die Bildbeschreibung ein


Ich mag das, aber was ist, wenn ich TableView habe, dann wird es mit dieser Leiste scrollen. Wie behebe ich das?
Maksim Kniazev

Hallo Maxim, ich kann dein Problem nicht verstehen. Bitte beschreiben Sie das gewünschte Ergebnis.
Vasily Bodnarchuk

Ok, ich verwende UITableViewController und wenn ich view.addSubview (toolBar!) Setze und meine Tabellenansicht scrolle, wird die Leiste mit tableView gescrollt. Ich möchte, dass sie eine feste untere Position hat
Maksim Kniazev

Ich denke, Sie sollten UIViewController mit UITableView (anstelle von UITableViewController) als Unteransicht verwenden.
Vasily Bodnarchuk

Ok Spasibo. Ich werde das versuchen
Maksim Kniazev

2

Ähnlich wie bei Matt RI wurde der Interface Builder verwendet. Aber ich wollte UIWebViewstattdessen 1 drinnen haben, damit ich etwas Fettdruck und anderen Text nicht haben kann (wie die Mail-App). So

  1. Fügen Sie stattdessen die Webansicht hinzu.
  2. Deaktivieren Sie die Option Undurchsichtig
  3. Stellen Sie sicher, dass der Hintergrund eine klare Farbe hat
  4. Schließen Sie alles an IBOutlet
  5. Verwenden Sie das Folgende html, um einen transparenten Hintergrund zu erhalten, damit die Symbolleiste durchscheint

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

1

Wenn Sie der Symbolleistenansicht eine Ansicht hinzufügen möchten, können Sie Folgendes versuchen:

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

1

Versuche dies:

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

Hinweis: self.barItemist ein UIBarButtonItemvon der Objektbibliothek hinzugefügt und zwischen zwei flexiblen Räumen.

Eine andere Möglichkeit besteht darin, die [self.barItem setCustom:view]Linie zu entfernen und die Parameter der label(Breite) so zu ändern , dass sie die gesamte Symbolleiste ausfüllt und die Ausrichtung auf die Mitte und die Schriftart selbst im Code festlegt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.