UINavigationBar多行标题

时间:2010-03-11 03:39:36

标签: uinavigationcontroller uilabel uinavigationbar title uinavigationitem

是否有一种直接的方法来覆盖导航控制器导航栏中当前导航栏项目的titleView?我已经尝试创建一个新的UIView并用我自己的UIVIew替换topView的titleView属性但没有成功。

基本上,我想要导航栏标题的多行标题。有什么建议吗?

10 个答案:

答案 0 :(得分:83)

设置titleView的{​​{1}}属性。例如,在视图控制器的UINavigationItem方法中,您可以执行以下操作:

viewDidLoad

它显示如下:

multi-line titlebar label

如果UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 480, 44)]; label.backgroundColor = [UIColor clearColor]; label.numberOfLines = 2; label.font = [UIFont boldSystemFontOfSize: 14.0f]; label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5]; label.textAlignment = UITextAlignmentCenter; label.textColor = [UIColor whiteColor]; label.text = @"This is a\nmultiline string"; self.navigationItem.titleView = label; #if !__has_feature(objc_arc) [label release]; #endif 不是titleView,请注意leftBarButtonItem属性为ignored

答案 1 :(得分:23)

快速解决方案:

NavigationBar中的2行:

private func setupTitleView() {
    let topText = NSLocalizedString("key", comment: "")
    let bottomText = NSLocalizedString("key", comment: "")

    let titleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
                           NSFontAttributeName : UIFont.<Font>]
    let subtitleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
                              NSFontAttributeName : UIFont.<Font>]

    let title:NSMutableAttributedString = NSMutableAttributedString(string: topText, attributes: titleParameters)
    let subtitle:NSAttributedString = NSAttributedString(string: bottomText, attributes: subtitleParameters)

    title.appendAttributedString(NSAttributedString(string: "\n"))
    title.appendAttributedString(subtitle)

    let size = title.size()

    let width = size.width
    guard let height = navigationController?.navigationBar.frame.size.height else {return}

    let titleLabel = UILabel(frame: CGRectMake(0,0, width, height))
    titleLabel.attributedText = title
    titleLabel.numberOfLines = 0
    titleLabel.textAlignment = .Center

    navigationItem.titleView = titleLabel
}

BarButton

中的2行
    let string = NSLocalizedString("key", comment: "")
    let attributes = [NSForegroundColorAttributeName : UIColor.<Color>,
                      NSFontAttributeName : UIFont.<Font>]
    let size = (string as NSString).sizeWithAttributes(attributes)
    guard let height = navigationController?.navigationBar.frame.size.height else {return}
    let button:UIButton = UIButton(frame: CGRectMake(0, 0, size.width, height))
    button.setAttributedTitle(NSAttributedString(string: string, attributes: attributes), forState: .Normal)
    button.addTarget(self, action: #selector(<SELECTOR>), forControlEvents: .TouchUpInside)
    button.titleLabel?.numberOfLines = 0
    button.titleLabel?.textAlignment = .Right
    let rightBarButton = UIBarButtonItem(customView: button)
    navigationItem.rightBarButtonItem = rightBarButton

结果 -

enter image description here

答案 2 :(得分:6)

经过大量的调整后,我仍然无法在iOS 8中获得petert的解决方案。这是适用于iOS 8/9的复制粘贴解决方案。积分转到Matt Curtis's github post

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if(!self.navigationItem.titleView){
        self.navigationItem.titleView = ({
            UILabel *titleView = [UILabel new];
            titleView.numberOfLines = 0;
            titleView.textAlignment = NSTextAlignmentCenter;
            titleView.attributedText = [[NSAttributedString alloc] initWithString:@"2\nLINES" attributes:
                self.navigationController.navigationBar.titleTextAttributes
            ];

            [titleView sizeToFit];
            // You'll need to set your frame otherwise if your line breaks aren't explcit.

            titleView;
        });
    }
}

答案 3 :(得分:4)

标签未居中时该怎么办

如果您遇到与我相同的问题 - 由于后退按钮,该标签不在navigationItem中居中,请将您的UILabel嵌入到UIView中。然后UILabel不会被迫使用它的文本,但是当它的宽度增加视图的宽度时停止增长。有关此问题的更多信息,请访问:Can't set titleView in the center of navigation bar because back button(Darren的回答)

不居中:

enter image description here

- (void)setTwoLineTitle:(NSString *)titleText color:(UIColor *)color font:(UIFont *)font {
    CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2;

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
    label.backgroundColor = [UIColor clearColor];
    label.numberOfLines = 2;
    label.font = font;
    label.adjustsFontSizeToFitWidth = YES;
    label.textAlignment = UITextAlignmentCenter;
    label.textColor = color;
    label.text = titleText;

    self.navigationItem.titleView = label;
}

居中:

enter image description here

- (void)setTwoLineTitle:(NSString *)titleText color:(UIColor *)color font:(UIFont *)font {
    CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2;

    UIView *wrapperView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
    label.backgroundColor = [UIColor clearColor];
    label.numberOfLines = 2;
    label.font = font;
    label.adjustsFontSizeToFitWidth = YES;
    label.textAlignment = UITextAlignmentCenter;
    label.textColor = color;
    label.text = titleText;

    [wrapperView addSubview:label];

    self.navigationItem.titleView = wrapperView;
}

答案 4 :(得分:3)

以下是处理多行标题的 Swift 3 版本:

override func viewDidLoad() {
    super.viewDidLoad()

    let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
    label.backgroundColor = .clear
    label.numberOfLines = 0
    label.textAlignment = .center
    label.font = UIFont.boldSystemFont(ofSize: 14.0)
    label.text = "This is a Multi-Line title of UINavigationBar"
    self.navigationItem.titleView = label
}

答案 5 :(得分:3)

这是 Swift 4 的做法 -

let upperTitle = NSMutableAttributedString(string: "\(text1)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProDisplay-Heavy", size: 17)!])
let lowerTitle = NSMutableAttributedString(string: "\n\((text2)!)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProText-Light", size: 11)! , NSAttributedStringKey.foregroundColor: UIColor(hex: "#607D8B")])

upperTitle.append(lowerTitle)

let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 400, height:44))
label1.numberOfLines = 0
label1.textAlignment = .center
label1.attributedText = upperTitle  //assign it to attributedText instead of text
self.navigationItem.titleView = label1

答案 6 :(得分:2)

快捷键4

extension UINavigationItem {
    @objc func setTwoLineTitle(lineOne: String, lineTwo: String) {
        let titleParameters = [NSAttributedStringKey.foregroundColor : UIColor.white,
                               NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 17)] as [NSAttributedStringKey : Any]
        let subtitleParameters = [NSAttributedStringKey.foregroundColor : UIColor.flatWhite(),
                                  NSAttributedStringKey.font : UIFont.systemFont(ofSize: 12)] as [NSAttributedStringKey : Any]

        let title:NSMutableAttributedString = NSMutableAttributedString(string: lineOne, attributes: titleParameters)
        let subtitle:NSAttributedString = NSAttributedString(string: lineTwo, attributes: subtitleParameters)

        title.append(NSAttributedString(string: "\n"))
        title.append(subtitle)

        let size = title.size()

        let width = size.width
        let height = CGFloat(44)

        let titleLabel = UILabel(frame: CGRect.init(x: 0, y: 0, width: width, height: height))
        titleLabel.attributedText = title
        titleLabel.numberOfLines = 0
        titleLabel.textAlignment = .center

        titleView = titleLabel
    }
}

字体,颜色和导航栏的高度在此处被硬编码。

答案 7 :(得分:2)

在 Swift 5 中,

    let wrapperView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width * 0.75, height: 44))
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width * 0.75, height: 44))
    label.backgroundColor = .clear
    label.numberOfLines = 2
    label.font = UIFont.boldSystemFont(ofSize: 16.0)
    label.textAlignment = .center
    label.textColor = .white
    label.text = "multi line text"
    wrapperView.addSubview(label)
    self.navigationItem.titleView = wrapperView

答案 8 :(得分:1)

除了来自@gbk的解决方案之外,大多数解决方案都使用硬编码高度44pt作为UIView(包装器视图)和UILabel。全部都是由代码创建的。我忽略了动态读取导航栏高度的@gbk解决方案。

我在iOS 11(iPhone 5s)上orientation = landscape遇到了问题。标签的高度不会调整,当我为横向设置一行文本时,文本会与导航栏的底部对齐。

不知怎的,我发现我可以在故事板中添加UILabel并为此创建一个IBOutlet。那不是更好吗?

  1. 在故事板中添加UIView到导航栏。将其拖动到导航栏上时,它将显示为蓝色框。如果出现垂直笔划,则将其添加到左/右栏按钮项目数组中。注意:只能有 ONE UIView。如果正确添加,它将显示在场景面板上的Navigation Item下(左侧)。
  2. 将UILabel拖入此UIView。 enter image description here
  3. 由于UIView将具有 NO SIZE 但集中在导航栏中,因此您无法添加四个零约束。只需向UILabel添加两个约束,使其位于superview的中心:将中心X和Y对齐到Superview。
  4. 像往常一样配置UILabel。对于多行,我将行数设置为零(0)。
  5. 在视图控制器上创建IBOutlet,您可以照常使用它。要使用不同大小的文本,请使用属性字符串(上面有很多解决方案)。
  6. 我在iPhone 5s上使用iOS 11.2.6进行测试,文本位于中心位置没有问题,在纵向和横向上工作正常。

答案 9 :(得分:0)

斯威夫特 5+ https://stackoverflow.com/a/68739808/6881070

提及一个功能链接中的非常简单流畅的解决方案