Add subtitle under the title in navigation bar con

2020-02-02 04:37发布

So I'm wanting to add a "subtitle" under the title in the navigation bar in navigation controller.

Mostly everything I look up so far wants me to use CGRect. I don't know a whole lot what that is and it sounds like its wanting me to create an entire new view which is not what I am wanting to do.

My question is, is there a dot method to adding a subtitle view easily?

The closest thing I found was posted on stack overflow and here is the link:

Create a subtitle in navigationbar

Apparently last year this worked but now I am getting errors and it's in my viewDidLoad...

I tried this:

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

It's the only thing that won't show any errors but still doesn't work. It literally does nothing. At least nothing visible at run time.

On a side note, swift is preferred. Thanks!

10条回答
Evening l夕情丶
2楼-- · 2020-02-02 04:42

Here is my version using a stack view on an extension.

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
        }
    }
查看更多
放荡不羁爱自由
3楼-- · 2020-02-02 04:45

Swift 4:

import UIKit

class NavigationTitleView: UIView {

    private var contentStackView = UIStackView()
    private var titleLabel = UILabel()
    private var subTitleLabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)

        viewConfig()
        addViewsConfig()
        layoutViewsConfig()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    func set(title: String, subTitle: String){

        self.titleLabel.text = title
        self.subTitleLabel.text = subTitle

    }

    private func viewConfig() {

        contentStackView.axis = .vertical
        contentStackView.alignment = .center
        contentStackView.distribution  = .fill
        contentStackView.spacing = 5


        self.backgroundColor = .clear
        self.titleLabel.textColor = .white
        self.self.subTitleLabel.textColor = .white

    }

    private func addViewsConfig() {

        contentStackView.addArrangedSubview(subTitleLabel)
        contentStackView.addArrangedSubview(titleLabel)
        self.addSubview(contentStackView)

    }

    private func layoutViewsConfig(){

        contentStackView.translatesAutoresizingMaskIntoConstraints = false
        contentStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0.0).isActive = true
        contentStackView.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0.0).isActive = true

    }

}

Use:

import UIKit

class  ViewController: UIViewController {

    private var navigationTitleView = NavigationTitleView()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.titleView = navigationTitleView
        navigationTitleView.set(title: "title", subTitle: "subTitle")

    }

}

enter image description here

查看更多
手持菜刀,她持情操
4楼-- · 2020-02-02 04:48

Though there is a solution but it has some known issues

Solution is writing a function like this

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
}

Using this function for custom navigation title view in viewDidLoad

self.navigationItem.titleView = setTitle("Title", subtitle: "SubTitle")

Only known issue is that if subtitle becomes very large than the misplacement occurs.

Final Outcome enter image description here

Source: https://gist.github.com/nazywamsiepawel/0166e8a71d74e96c7898

查看更多
等我变得足够好
5楼-- · 2020-02-02 04:50

Another solution, using only one label and NSAttributedString to differentiate between title and subtitle (with different font sizes, weights, colors, etc.) instead. Removes the problem of different label alignment.

extension UIViewController {
    func setTitle(_ title: String, subtitle: String) {
        let rect = CGRect(x: 0, y: 0, width: 400, height: 50)
        let titleSize: CGFloat = 20     // adjust as needed
        let subtitleSize: CGFloat = 15

        let label = UILabel(frame: rect)
        label.backgroundColor = .clear
        label.numberOfLines = 2
        label.textAlignment = .center
        label.textColor = .black

        let text = NSMutableAttributedString()
        text.append(NSAttributedString(string: title, attributes: [.font : UIFont.boldSystemFont(ofSize: titleSize)]))
        text.append(NSAttributedString(string: "\n\(subtitle)", attributes: [.font : UIFont.systemFont(ofSize: subtitleSize)]))
        label.attributedText = text
        self.navigationItem.titleView = label
    }
}

Custom titleView based in part on https://stackoverflow.com/a/34298491/3918865

查看更多
太酷不给撩
6楼-- · 2020-02-02 04:56

I really liked @user2325031's answer, but found that sizing the labels to fit and setting the frame wasn't needed. I also set the stackView's alignment to .center per @GerardoMR's suggestion.

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
    }

}
查看更多
迷人小祖宗
7楼-- · 2020-02-02 05:02

This will do the job:

let searchController = UISearchController(searchResultsController: nil)
        if #available(iOS 11.0, *) {
            self.navigationItem.searchController = searchController
        } else {
            self.navigationItem.titleView = searchController.searchBar
        }
查看更多
登录 后发表回答