在Xcode的导航栏控制器的标题下添加字幕

Adr*_*rez 38 uinavigationbar uinavigationcontroller uinavigationitem swift

所以我想在导航控制器的导航栏中添加标题下的"副标题".

到目前为止,我查找的大部分内容都要我使用CGRect.我不知道那是什么,这听起来像是想要我创建一个全新的视图而不是我想做的事情.

我的问题是,有一种点方法可以轻松添加字幕视图吗?

我发现的最接近的事情是在堆栈溢出时发布,这是链接:

在导航栏中创建一个副标题

显然去年这有效,但现在我得到错误,它在我的viewDidLoad ...

我试过这个:

self.navigationController?.navigationItem.prompt ="Subtitle Here"

这是唯一不会显示任何错误但仍然不起作用的东西.它实际上什么都不做.在运行时至少没有任何可见的东西.

另一方面,swift是首选.谢谢!

小智 62

这是我的版本在扩展上使用堆栈视图.

extension UINavigationItem {



     func setTitle(title:String, subtitle:String) {

            let one = UILabel()
            one.text = title
            one.font = UIFont.systemFont(ofSize: 17)
            one.sizeToFit()

            let two = UILabel()
            two.text = subtitle
            two.font = UIFont.systemFont(ofSize: 12)
            two.textAlignment = .center
            two.sizeToFit()



            let stackView = UIStackView(arrangedSubviews: [one, two])
            stackView.distribution = .equalCentering
            stackView.axis = .vertical
            stackView.alignment = .center

            let width = max(one.frame.size.width, two.frame.size.width)
            stackView.frame = CGRect(x: 0, y: 0, width: width, height: 35)

            one.sizeToFit()
            two.sizeToFit()



            self.titleView = stackView
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,这是更清晰的答案,它没有神奇的数字作为第一个答案.设置轴后我只会添加`stackView.alignment = .center`,否则如果字幕较大则不会完全居中.此外,我会删除最后两次调用`sizeToFit()`,因为你在标签上调用了它们. (9认同)
  • 从导航控制器推送任何变通方法时,标题和副标题从左侧滑动到中心 (3认同)

Raj*_*ari 46

虽然有一个解决方案,但它有一些已知的问题

解决方案是编写这样的函数

func setTitle(title:String, subtitle:String) -> UIView {
    let titleLabel = UILabel(frame: CGRectMake(0, -2, 0, 0))

    titleLabel.backgroundColor = UIColor.clearColor()
    titleLabel.textColor = UIColor.grayColor()
    titleLabel.font = UIFont.boldSystemFontOfSize(17)
    titleLabel.text = title
    titleLabel.sizeToFit()

    let subtitleLabel = UILabel(frame: CGRectMake(0, 18, 0, 0))
    subtitleLabel.backgroundColor = UIColor.clearColor()
    subtitleLabel.textColor = UIColor.blackColor()
    subtitleLabel.font = UIFont.systemFontOfSize(12)
    subtitleLabel.text = subtitle
    subtitleLabel.sizeToFit()

    let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 30))
    titleView.addSubview(titleLabel)
    titleView.addSubview(subtitleLabel)

    let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width

    if widthDiff < 0 {
        let newX = widthDiff / 2
        subtitleLabel.frame.origin.x = abs(newX)
    } else {
        let newX = widthDiff / 2
        titleLabel.frame.origin.x = newX
    }

    return titleView
}
Run Code Online (Sandbox Code Playgroud)

使用此功能进行自定义导航标题视图 viewDidLoad

self.navigationItem.titleView = setTitle("Title", subtitle: "SubTitle")
Run Code Online (Sandbox Code Playgroud)

唯一已知的问题是如果字幕变得非常大,则发生错位.

最终结果 在此输入图像描述

资料来源:https://gist.github.com/nazywamsiepawel/0166e8a71d74e96c7898

  • 从导航控制器推送任何变通方法@naveed时,标题和副标题从左侧滑动到中心 (3认同)

Adr*_*rez 11

非常感谢您的回答!@RajanMaheshwari

除了使用widthDiff创建的if语句之外,您的编码工作正常.

我调整了一点,一切顺利.

if widthDiff < 0 {
        let newX = widthDiff / 2
        subtitleLabel.frame.origin.x = abs(newX)
    } else {
        let newX = widthDiff / 2
        titleLabel.frame.origin.x = newX
    }
Run Code Online (Sandbox Code Playgroud)

再次感谢您的回复!


小智 7

@iosjillian的Swift 4扩展程序效果很好,添加了更多功能以纪念栏的外观和用户字体首选项:

import UIKit

extension UINavigationItem {

  func setTitle(_ title: String, subtitle: String) {
    let appearance = UINavigationBar.appearance()
    let textColor = appearance.titleTextAttributes?[NSAttributedString.Key.foregroundColor] as? UIColor ?? .black

    let titleLabel = UILabel()
    titleLabel.text = title
    titleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.headline)
    titleLabel.textColor = textColor

    let subtitleLabel = UILabel()
    subtitleLabel.text = subtitle
    subtitleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.subheadline)
    subtitleLabel.textColor = textColor.withAlphaComponent(0.75)

    let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
    stackView.distribution = .equalCentering
    stackView.alignment = .center
    stackView.axis = .vertical

    self.titleView = stackView
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

如果有人正在寻找Objective-C上述解决方案的代码:

   UILabel *title = [[UILabel alloc]init];
   UILabel *subtitle = [[UILabel alloc]init];

   [title setFont:[UIFont systemFontOfSize:12]];
   [title setTextColor:[UIColor whiteColor]];
   [title setFont:[UIFont systemFontOfSize:17]];
   [title sizeToFit];
   title.text = @"Title";

   [subtitle setTextColor:[UIColor whiteColor]];
   [subtitle setFont:[UIFont systemFontOfSize:12]];
   [subtitle setTextAlignment:NSTextAlignmentCenter];
   [subtitle sizeToFit];
   subtitle.text = @"Subtitle Title";

   UIStackView *stackVw = [[UIStackView alloc]initWithArrangedSubviews:@[title,subtitle]];
   stackVw.distribution = UIStackViewDistributionEqualCentering;
   stackVw.axis = UILayoutConstraintAxisVertical;
   stackVw.alignment =UIStackViewAlignmentCenter;


   [stackVw setFrame:CGRectMake(0, 0, MAX(title.frame.size.width, subtitle.frame.size.width), 35)];
   self.navigationItem.titleView = stackVw;
Run Code Online (Sandbox Code Playgroud)


小智 5

我真的很喜欢@user2325031的答案,但发现不需要调整标签大小以适应并设置框架。我还根据 @GerardoMR 的建议将 stackView 的对齐方式设置为 .center 。

extension UINavigationItem {

    func setTitle(_ title: String, subtitle: String) {
        let titleLabel = UILabel()
        titleLabel.text = title
        titleLabel.font = .systemFont(ofSize: 17.0)
        titleLabel.textColor = .black

        let subtitleLabel = UILabel()
        subtitleLabel.text = subtitle
        subtitleLabel.font = .systemFont(ofSize: 12.0)
        subtitleLabel.textColor = .gray

        let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
        stackView.distribution = .equalCentering
        stackView.alignment = .center
        stackView.axis = .vertical

        self.titleView = stackView
    }

}
Run Code Online (Sandbox Code Playgroud)