Thêm UILabel vào UIToolbar


97

Tôi đang cố gắng thêm nhãn vào thanh công cụ của mình. Nút hoạt động tốt, tuy nhiên khi tôi thêm đối tượng nhãn, nó bị treo. Bất kỳ ý tưởng?

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

Câu trả lời:


128

Hãy xem xét điều này

[[UIBarButtonItem alloc] initWithCustomView:yourCustomView];

Về cơ bản mọi mục phải là một "nút" nhưng chúng có thể được khởi tạo với bất kỳ chế độ xem nào bạn yêu cầu. Đây là một số mã ví dụ. Lưu ý, vì các nút khác thường nằm trên thanh công cụ, nên các dấu cách được đặt ở mỗi bên của nút tiêu đề để nó được căn giữa.

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
Lưu ý rằng nếu bạn chọn con đường này, bạn phải tạo kiểu cho nhãn của mình một cách thích hợp (label.backgroundColor = [UIColor clearColor], v.v.). Bạn cũng có thể kết hợp UIBarButtonItem để được tạo kiểu Plain sẽ mang lại cho bạn một cái nhìn tương tự
khôn ngoanquark

Tôi biết đây là một bài viết thực sự cũ, nhưng tôi có một câu hỏi về câu trả lời này. Khi điều này được thực hiện, có cách nào để truy cập titleLabel sau này để thay đổi nó không, hay là không thể vì mọi thứ đã được phát hành?
Ryan

Ryan, UILabel có thể vẫn tồn tại - nó là self.titleLabel. Ví dụ này cần một thuộc tính được khai báo và tổng hợp cho UILabel * titleLabel, nhưng mã đó không được hiển thị. Nếu bạn có quyền truy cập vào đối tượng (có thể là UIViewController) chạy mã này, bạn có thể truy cập titleLabel của nó. Ví dụ: bạn có thể thêm một phương thức trên bộ điều khiển chế độ xem, chuyển vào tiêu đề mới mà bạn muốn, rồi gọi [self.titleLabel setText: newTitle].
Steve Liddle

7
Bạn có muốn thêm khoảng đệm thứ hai sau mục thanh nút tiêu đề không?
len

121

Đối với những người sử dụng Trình tạo giao diện để bố trí của bạn UIToolBar, cũng có thể thực hiện việc này chỉ bằng Trình tạo giao diện.

Để thêm a UILabelvào a, UIToolBarbạn cần thêm một UIViewđối tượng chung UIToolBarvào IB của mình bằng cách kéo một UIViewđối tượng mới lên trên UIToolBar. IBsẽ tự động tạo một UIBarButtonItemsẽ được khởi tạo với tùy chỉnh của bạn UIView. Tiếp theo, thêm a UILabelvào UIViewvà chỉnh sửa UILabelđồ họa để phù hợp với phong cách ưa thích của bạn. Sau đó, bạn có thể thiết lập trực quan các bộ đệm cố định và / hoặc thay đổi như mong muốn để định vị UILabelphù hợp.

Bạn cũng phải thiết lập các nền tảng của cả hai UILabelUIViewđể clearColorđể có được UIToolBarhiển thị thông qua một cách chính xác dưới UILabel.


2
Mẹo hay, không biết bạn có thể làm được trong Trình tạo giao diện. Cảm ơn rât nhiều.
Rafael Bugajewski

Có cách nào để thêm UIButton với hình ảnh tùy chỉnh bằng phương pháp đó không? Tôi có thể thêm UIButton, nhưng hình ảnh không hiển thị.
cannyboy.

4
Tôi dường như không thể làm cho việc này hoạt động. Khi tôi kéo một UIView vào thanh công cụ, nó sẽ được đặt bên trong bộ điều khiển chế độ xem, không phải trên thanh công cụ. Ngoài ra, chúng tôi thực hiện việc này trong bộ điều khiển điều hướng hay trong bộ điều khiển chế độ xem?
guptron

1
Điều đó dường như không hoạt động. Nếu nó hoạt động một lần cách đây khá lâu, thì không còn trong XCode 6 ...
Frédéric Adda

1
Bạn nên cập nhật câu trả lời của mình để chỉ ra rằng điều này chỉ hoạt động với các thanh công cụ được thêm vào bộ điều khiển chế độ xem theo cách thủ công; nó không hoạt động với thanh công cụ được thêm vào cho bạn.
James Bush

32

Tôi thấy câu trả lời của answerBot rất hữu ích, nhưng tôi nghĩ rằng tôi đã tìm thấy một cách thậm chí còn dễ dàng hơn, trong Trình tạo giao diện:

  • tạo UIBarButtonItem và thêm nó vào Thanh công cụ của bạn trong Trình tạo giao diện

nhập mô tả hình ảnh ở đây

  • Bỏ chọn "đã bật" cho BarButtonItem này

nhập mô tả hình ảnh ở đây

  • cắm BarButtonItem này vào một thuộc tính trong lớp của bạn (đây là trong Swift, nhưng sẽ rất giống trong Obj-C):

    @IBOutlet private weak var lastUpdateButton: UIBarButtonItem! // Dummy barButtonItem whose customView is lastUpdateLabel
  • thêm một thuộc tính khác cho chính Nhãn:

    private var lastUpdateLabel = UILabel(frame: CGRectZero)
  • trong viewDidLoad, hãy thêm mã sau để đặt các thuộc tính cho nhãn của bạn và thêm nó làm customView của BarButtonItem của bạn

    // Dummy button containing the date of last update
    lastUpdateLabel.sizeToFit()
    lastUpdateLabel.backgroundColor = UIColor.clearColor()
    lastUpdateLabel.textAlignment = .Center
    lastUpdateButton.customView = lastUpdateLabel
  • Để cập nhật UILabelvăn bản:

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

Kết quả :

nhập mô tả hình ảnh ở đây

Bạn phải gọi lastUpdateLabel.sizetoFit()mỗi khi cập nhật văn bản nhãn


1
Tôi đã tạo một UIBarButtonItem giống như bạn, để nó được bật và chồng nhãn bằng cách sử dụng mã sau: UILabel* label = [[UILabel alloc] init]; label.text = @"Hello"; label.font = [UIFont systemFontOfSize:16]; [label sizeToFit]; self.barItem.customView = label;
Brett Donald

6

Một trong những điều tôi đang sử dụng thủ thuật này là để nhanh chóng một UIActivityIndicatorViewtrên đỉnh UIToolBar, một cái gì đó mà nếu không sẽ không thực hiện được. Ví dụ ở đây tôi có a UIToolBarvới 2 UIBarButtonItem, a FlexibleSpaceBarButtonItem, và sau đó là cái khác UIBarButtonItem. Tôi muốn chèn một UIActivityIndicatorViewvào UIToolBargiữa khoảng trống linh hoạt và nút cuối cùng (bên tay phải). Vì vậy, RootViewControllertôi làm như sau,

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

Mã này làm rò rỉ bộ nhớ được cấp phát cho UIBarButtonItem với chế độ xem chỉ báo hoạt động tùy chỉnh. (Nó cũng làm rò rỉ bộ nhớ của chỉ báo hoạt động, nhưng tôi cho rằng nó đang được phát hành bên dưới phần cuối của đoạn mã.
erikprice

3

Chi tiết

  • Xcode 10.2.1 (10E1001), Swift 5

Đầy đủ mẫu

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

Kết quả

nhập mô tả hình ảnh ở đây


Tôi thích điều này, nhưng nếu tôi có TableView thì nó sẽ cuộn bằng thanh này. Làm cách nào để khắc phục điều đó?
Maksim Kniazev

Xin chào Maxim, tôi không thể hiểu vấn đề của bạn. Vui lòng mô tả kết quả bạn muốn nhận được.
Vasily Bodnarchuk

Được rồi, tôi đang sử dụng UITableViewController và nếu tôi đặt view.addSubview (toolBar!) Và cuộn chế độ xem bảng của mình, thanh sẽ cuộn với tableView, tôi muốn nó có vị trí dưới cùng cố định
Maksim Kniazev

Tôi nghĩ, bạn nên sử dụng UIViewController với UITableView (thay vì UITableViewController) làm chế độ xem phụ.
Vasily Bodnarchuk

Ok spaibo. tôi sẽ cố gắng làm điều đó
Maksim Kniazev

2

Tương tự như Matt RI đã sử dụng trình tạo giao diện. Nhưng tôi muốn có 1 UIWebViewbên trong thay thế để tôi có thể có một số văn bản được in đậm và văn bản khác thì không (như ứng dụng mail). Vì thế

  1. Thay vào đó, hãy thêm chế độ xem web.
  2. Bỏ chọn trong suốt
  3. Đảm bảo nền có màu rõ ràng
  4. Kết nối mọi thứ với IBOutlet
  5. Sử dụng phần bên dưới htmlđể có nền trong suốt để thanh công cụ chiếu xuyên qua

Mã:

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

Nếu bạn muốn thêm chế độ xem lên chế độ xem thanh công cụ, bạn có thể thử cách này:

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

1

Thử cái này:

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

Lưu ý: self.barItemlà một UIBarButtonItemđược thêm vào từ thư viện đối tượng và được đặt giữa hai không gian linh hoạt.

một cách khác là xóa [self.barItem setCustom:view]dòng và thay đổi các thông số của label(chiều rộng) để nó lấp đầy toàn bộ thanh công cụ và đặt căn chỉnh ở giữa và phông chữ của chính bạn trong mã,

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.