23

I am trying to add two labels in the place where the title is shown in navigation bar, but I am struggling to do so. It would be very nice if I could achieve this with storyboard but as I can see I cannot do it.

As I have seen I need to use navigationItem but I do not know how exactly to do that. If anyone have any example or if anyone could explain me more specifically how to do so would be wonderful.

And I need to mention that I am completely unfamiliar with Obj-C, so any help would need to be in Swift.

Ilir V. Gruda
  • 1,562
  • 5
  • 17
  • 23

2 Answers2

35

I am not sure if you can do it from the storyboard, but if you want to add two title labels, you can do the following in the viewDidLoad() method of the view controller for which you want the two titles:

if let navigationBar = self.navigationController?.navigationBar {
    let firstFrame = CGRect(x: 0, y: 0, width: navigationBar.frame.width/2, height: navigationBar.frame.height)
    let secondFrame = CGRect(x: navigationBar.frame.width/2, y: 0, width: navigationBar.frame.width/2, height: navigationBar.frame.height)

    let firstLabel = UILabel(frame: firstFrame)
    firstLabel.text = "First"

    let secondLabel = UILabel(frame: secondFrame)
    secondLabel.text = "Second"

    navigationBar.addSubview(firstLabel)
    navigationBar.addSubview(secondLabel)
}

In this way you can add as many subviews as you want to the navigation bar

Xavier Lowmiller
  • 1,381
  • 1
  • 15
  • 24
vdawg
  • 484
  • 5
  • 6
  • if u please can help me with an additional question. How can I add constrains to these labels so they will be placed center horizontally and one underneath the other one – Ilir V. Gruda Jul 11 '15 at 10:41
  • 1
    @vdawg labels are aligning back to back...plz tell us how to align labels one above another – Bevan Mar 08 '16 at 19:56
  • 1
    @Bevan you can just change the firstFrame' and secondFrame properties to adjust the frames of the labels let firstFrame = CGRect(x: 0, y: 0, width: navigationBar.frame.width, height: navigationBar.frame.height/2) let secondFrame = CGRect(x: 0, y: navigationBar.frame.height/2, width: navigationBar.frame.width, height: navigationBar.frame.height/2) – vdawg Mar 09 '16 at 01:07
  • 1
    In my case Center Align also did the trick : firstLabel.textAlignment = .Center – ioopl Jul 22 '16 at 22:13
22

Here's an implementation that uses a stack view instead, which also gives you some versatility with layout of the labels:

class ViewController: UIViewController {

    lazy var titleStackView: UIStackView = {
        let titleLabel = UILabel()
        titleLabel.textAlignment = .center
        titleLabel.text = "Title"
        let subtitleLabel = UILabel()
        subtitleLabel.textAlignment = .center
        subtitleLabel.text = "Subtitle"
        let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
        stackView.axis = .vertical
        return stackView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.titleView = titleStackView
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        if view.traitCollection.horizontalSizeClass == .compact {
            titleStackView.axis = .vertical
            titleStackView.spacing = UIStackView.spacingUseDefault
        } else {
            titleStackView.axis = .horizontal
            titleStackView.spacing = 20.0
        }
    }
}

Demonstrates using a stack view to create a custom navigation item's title view

Scott Gardner
  • 8,603
  • 1
  • 44
  • 36