UINavigationBar多行标题

发布于 2024-08-24 06:57:55 字数 150 浏览 6 评论 0原文

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

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

Is there a straightforward way of overriding the titleView of the current navigation bar item in a navigation bar within a navigation controller? I've tried creating a new UIView and replacing the titleView property of topView with my own UIVIew with no success.

Basically, I want a multi-line title for the navigation bar title. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

不知所踪 2024-08-31 06:57:55

设置 UINavigationItemtitleView 属性。例如,在视图控制器的 viewDidLoad 方法中,您可以执行以下操作:

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不是nil

Set the titleView property of the UINavigationItem. For example, in the view controller's viewDidLoad method you could do something like:

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

It shows up like this:

multi-line titlebar label

Remember the titleView property is ignored if leftBarButtonItem is not nil.

能怎样 2024-08-31 06:57:55

对于斯威夫特:

let label = UILabel(frame: CGRectMake(0, 0, UIScreen.main.bounds.width, 44))
label.backgroundColor = UIColor.clearColor()
label.numberOfLines = 0
label.textAlignment = NSTextAlignment.Center
label.text = "multiline string"
self.navigationItem.titleView = label

对于斯威夫特4:

    let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: 44.0))
    label.backgroundColor = UIColor.clear
    label.numberOfLines = 0
    label.textAlignment = NSTextAlignment.center
    label.text = "first line\nsecond line"
    self.navigationItem.titleView = label   

for Swift:

let label = UILabel(frame: CGRectMake(0, 0, UIScreen.main.bounds.width, 44))
label.backgroundColor = UIColor.clearColor()
label.numberOfLines = 0
label.textAlignment = NSTextAlignment.Center
label.text = "multiline string"
self.navigationItem.titleView = label

for swift 4:

    let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: 44.0))
    label.backgroundColor = UIColor.clear
    label.numberOfLines = 0
    label.textAlignment = NSTextAlignment.center
    label.text = "first line\nsecond line"
    self.navigationItem.titleView = label   
执手闯天涯 2024-08-31 06:57:55

Swift 解决方案:

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

    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

结果中的 2 行 -

在此处输入图像描述

Swift solution:

2 lines in NavigationBar:

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
}

2 line in BarButton

    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

result -

enter image description here

烈酒灼喉 2024-08-31 06:57:55

经过大量调整后,我仍然无法让 Petert 的解决方案在 iOS 8 中为我工作。这是适用于 iOS 8/9 的可复制粘贴的解决方案。感谢 Matt Curtis 的 github 帖子

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

After a lot of tweaking, I still couldn't get petert's solution to work for me in iOS 8. Here's a copy-paste-able solution for iOS 8/9. Credit goes to 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;
        });
    }
}
请别遗忘我 2024-08-31 06:57:55

当标签不居中时该怎么办

如果您遇到与我相同的问题 - 由于后退按钮,标签未在 navigationItem 中居中,请将您的 UILabel 嵌入到 UIView 中。然后,UILabel 不会被迫随其文本一起增长,但当其宽度提高视图宽度时停止增长。有关此问题的更多信息,您可以在这里找到:无法将 titleView 设置在导航栏的中心,因为后退按钮(达伦的回答)

未居中:

在此处输入图像描述

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

居中:

在此处输入图像描述

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

What to do when label is not centered

If you encounter same issue as me - that label is not centered in navigationItem because of back button, embed your UILabel to UIView. UILabel is then not forced to grow with it's text, but stop growing when it's width raise view's width. More about this issue you can find here: Can't set titleView in the center of navigation bar because back button ( Darren's answer )

Not centered:

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

Centered:

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;
}
长安忆 2024-08-31 06:57:55

这是处理多行标题的 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
}

Here is a Swift 3 version of handling a multiline title:

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
}
沙与沫 2024-08-31 06:57:55

这是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

Here's a Swift 4 way of doing it-

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
没有伤那来痛 2024-08-31 06:57:55

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

字体、颜色和导航栏高度均在此处进行硬编码。

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

Font, color, and navigation bar height are hardcoded here.

你げ笑在眉眼 2024-08-31 06:57:55

在 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

In 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
聽兲甴掵 2024-08-31 06:57:55

大多数解决方案(除了 @gbk 中的解决方案)都对 UIView(包装视图)和 UILabel 使用硬编码高度 44pt。一切都是由代码创建的。我忽略了动态读取导航栏高度的@gbk 解决方案。

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

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

  1. 将 UIView 添加到情节提要中的导航栏。将其拖动到导航栏上时,它将显示为蓝色框。如果出现垂直笔划,则表明您正在将其添加到左/右栏按钮项目数组中。注意:只能有一个 UIView。如果添加正确,它将出现在场景面板(左侧)的Navigation Item 下。
  2. 将 UILabel 拖到此 UIView 中。 输入图片此处描述
  3. 由于 UIView 将没有大小,但集中在导航栏中,因此您无法添加四个零的约束。只需向 UILabel 添加两个约束,使其位于超级视图的中心:将中心 X 和 Y 与超级视图对齐。
  4. 像往常一样配置 UILabel。对于多行,我将行数设置为零 (0)。
  5. 在视图控制器上创建一个IBOutlet,您就可以像往常一样使用它。要具有不同大小的文本,请使用属性字符串(上面有很多解决方案)。

我在装有 iOS 11.2.6 的 iPhone 5s 上进行了测试,文本正好位于中心位置,没有任何问题,在纵向和横向上都可以正常工作。

Most of the solutions, except the one from @gbk, use hardcoded height 44pt for the UIView (wrapper view) and UILabel. All are created by codes. I overlooked @gbk solution which dynamically read height of navigation bar.

I ran into problem when orientation = landscape on iOS 11 (iPhone 5s). The label's height won't adjust and when I set one line of text for landscape, the text align to bottom of navigation bar.

Somehow I found that I can add the UILabel in Storyboard and create an IBOutlet for that. Isn't that nicer?

  1. Add an UIView to navigation bar in storyboard. When dragging it over navigation bar, it will appears as a blue box. If a vertical stroke appears, you are adding it to left/right bar button items array. Note: there can only be ONE UIView. If you add it correctly, it will appear under Navigation Item on the scene panel (on left).
  2. Drag a UILabel into this UIView. enter image description here
  3. Since UIView will have NO SIZE but centralized in navigation bar, you cannot add four zero's constraint. Just add two constraints to the UILabel so it position in the center of superview: Align Center X and Y to Superview.
  4. Configure UILabel as usual. For multiple line, I set number of lines to zero (0).
  5. Create an IBOutlet on your view controller and you can use it as usual. To have different size of text, use attribute string (lots of solutions above).

I tested on iPhone 5s with iOS 11.2.6 and the text just position in center with no problem, work fine on portrait and landscape.

玩世 2024-08-31 06:57:55

Swift 5+ https://stackoverflow.com/a/68739808/6881070

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

Swift 5+ https://stackoverflow.com/a/68739808/6881070

very easy and smooth solution in one function link is mention

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文