Добавление UILabel в UIToolbar


97

Я пытаюсь добавить ярлык на свою панель инструментов. Кнопка работает отлично, но когда я добавляю объект метки, происходит сбой. Любые идеи?

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

Ответы:


128

Взгляните на это

[[UIBarButtonItem alloc] initWithCustomView:yourCustomView];

По сути, каждый элемент должен быть «кнопкой», но они могут быть созданы с любым просмотром, который вам нужен. Вот пример кода. Обратите внимание: поскольку другие кнопки обычно находятся на панели инструментов, разделители размещаются с каждой стороны кнопки заголовка, чтобы она оставалась по центру.

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
Обратите внимание, что если вы выбрали этот путь, вы должны соответствующим образом стилизовать метку (label.backgroundColor = [UIColor clearColor] и т. Д.). Вы также можете инициализировать UIBarButtonItem в стиле Plain, который будет выглядеть примерно так же
Wyquark

Я знаю, что это действительно старый пост, но у меня есть вопрос по этому поводу. Как только это будет сделано, есть ли способ позже получить доступ к titleLabel, чтобы изменить его, или это невозможно, поскольку все было выпущено?
Райан

Райан, возможно, UILabel все еще существует - это self.titleLabel. В этом примере необходимо объявить и синтезировать свойство для UILabel * titleLabel, но этот код не показан. Если у вас есть доступ к объекту (возможно, UIViewController), который запускает этот код, вы можете получить доступ к его titleLabel. Например, вы можете добавить метод в контроллер представления, передать новый заголовок, который вы хотите, а затем вызвать [self.titleLabel setText: newTitle].
Стив Лиддл,

7
Разве вы не хотели бы добавить вторую прокладку после элемента строки заголовка?
Len

121

Для тех, кто использует Interface Builder для компоновки вашего UIToolBar , это также можно сделать, используя только Interface Builder.

Чтобы добавить UILabelв объект, UIToolBarвам нужно добавить общий UIViewобъект в свой UIToolBarIB, перетащив новый UIViewобъект поверх вашего UIToolBar. IBавтоматически создаст UIBarButtonItemфайл, который будет инициализирован вашим custom UIView. Затем добавьте UILabelк UIViewи отредактируйте UILabelграфическое изображение в соответствии с вашим предпочтительным стилем. Затем вы можете визуально настроить фиксированные и / или переменные распорки по своему желанию, чтобы расположить их UILabelсоответствующим образом.

Вы также должны установить фон как для, так UILabelи UIViewдля, clearColorчтобы они UIToolBarправильно отображались под UILabel.


2
Хороший трюк, не знал, что это можно сделать в Interface Builder. Большое спасибо.
Рафаэль Бугаевски

Есть ли способ добавить UIButton с пользовательским изображением с помощью этого метода? Я могу добавить UIButton, но изображение не отображается.
cannyboy

4
Кажется, я не могу заставить это работать. Когда я перетаскиваю UIView на панель инструментов, он оказывается внутри контроллера представления, а не на панели инструментов. Кроме того, делаем ли мы это в контроллере навигации или в контроллере представления?
guptron

1
Похоже, это не работает. Если бы это работало когда-то давным-давно, больше не в XCode 6 ...
Фредерик Адда

1
Вы должны обновить свой ответ, чтобы указать, что это работает только с панелями инструментов, добавленными к контроллеру представления вручную; он не работает с добавленной для вас панелью инструментов.
Джеймс Буш

32

Я нашел ответ answerBot очень полезным, но я думаю, что нашел еще более простой способ в Interface Builder:

  • создайте UIBarButtonItem и добавьте его на свою панель инструментов в Interface Builder

введите описание изображения здесь

  • Снимите флажок "включен" для этого BarButtonItem

введите описание изображения здесь

  • подключите этот BarButtonItem к свойству в своем классе (это в Swift, но будет очень похоже на Obj-C):

    @IBOutlet private weak var lastUpdateButton: UIBarButtonItem! // Dummy barButtonItem whose customView is lastUpdateLabel
  • добавьте еще одно свойство для самого ярлыка:

    private var lastUpdateLabel = UILabel(frame: CGRectZero)
  • в viewDidLoad добавьте следующий код, чтобы установить свойства вашей метки, и добавьте его как customView вашего BarButtonItem

    // Dummy button containing the date of last update
    lastUpdateLabel.sizeToFit()
    lastUpdateLabel.backgroundColor = UIColor.clearColor()
    lastUpdateLabel.textAlignment = .Center
    lastUpdateButton.customView = lastUpdateLabel
  • Чтобы обновить UILabelтекст:

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

Результат:

введите описание изображения здесь

Приходится звонить lastUpdateLabel.sizetoFit()каждый раз при обновлении текста метки


1
Я создал UIBarButtonItem так же, как вы, оставил его включенным и наложил метку, используя следующий код: UILabel* label = [[UILabel alloc] init]; label.text = @"Hello"; label.font = [UIFont systemFontOfSize:16]; [label sizeToFit]; self.barItem.customView = label;
Бретт Дональд

6

Одна из вещей, для которых я использую этот трюк, - это создать экземпляр UIActivityIndicatorViewповерх UIToolBar, что в противном случае было бы невозможно. Например здесь у меня есть UIToolBarс 2 UIBarButtonItem, в FlexibleSpaceBarButtonItem, а затем другой UIBarButtonItem. Я хочу , чтобы вставить UIActivityIndicatorViewв UIToolBarмежду гибким пространством и кнопками окончательной (правой). Итак, RootViewControllerя делаю следующее:

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

Этот код приводит к утечке памяти, выделенной для UIBarButtonItem с помощью пользовательского представления индикатора активности. (Это также приводит к утечке памяти индикатора активности, но я предполагаю, что это происходит ниже конца фрагмента кода.
erikprice

3

подробности

  • Xcode 10.2.1 (10E1001), Swift 5

Полный образец

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

Результат

введите описание изображения здесь


Мне это нравится, но что, если у меня есть TableView, он будет прокручиваться вместе с этой полосой. Как мне это исправить?
Максим Князев

Привет Максим, я не понимаю твою проблему. Опишите, пожалуйста, результат, который вы хотите получить.
Василий Боднарчук

Хорошо, я использую UITableViewController, и если я устанавливаю view.addSubview (toolBar!) И прокручиваю свой tableview, полоса прокручивается с помощью tableView, я хочу, чтобы у нее было фиксированное нижнее положение
Максим Князев

Я думаю, вам следует использовать UIViewController с UITableView (вместо UITableViewController) в качестве подпредставления.
Василий Боднарчук

Хорошо, спасибо. Я попробую
Максим Князев

2

Подобно Мэтту Р. Я использовал построитель интерфейсов. Но UIWebViewвместо этого я хотел иметь 1 внутри, чтобы можно было выделить текст жирным шрифтом, а другой - нет (например, почтовое приложение). Так

  1. Вместо этого добавьте веб-просмотр.
  2. Снимите флажок непрозрачный
  3. Убедитесь, что фон чистый
  4. Подключите все к IBOutlet
  5. Используйте изображение ниже, htmlчтобы иметь прозрачный фон, чтобы панель инструментов просвечивала сквозь

Код:

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

Если вы хотите добавить представление на панель инструментов, вы можете попробовать следующее:

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

1

Попробуй это:

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

Примечание: self.barItemэтоUIBarButtonItem добавлено из библиотеки объектов и помещается между двумя гибкими пространствами.

другой способ - удалить [self.barItem setCustom:view]строку и изменить параметры label(ширины) так, чтобы она заполняла всю панель инструментов, и самостоятельно установить выравнивание по середине и шрифту в коде,

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.