Add subtitle under the title in navigation bar controller in Xcode
Solution 1
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.
Source: https://gist.github.com/nazywamsiepawel/0166e8a71d74e96c7898
Solution 2
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
}
}
Solution 3
@iosjillian's Swift 4 extension works great, adding a bit more to honor the bar's appearance and user font preferences:
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
}
}
Solution 4
Thanks a lot for your answer! @RajanMaheshwari
Your coding worked perfectly except the if statement you made with the widthDiff..
I adjusted it a little bit and everything worked smoothly.
if widthDiff < 0 {
let newX = widthDiff / 2
subtitleLabel.frame.origin.x = abs(newX)
} else {
let newX = widthDiff / 2
titleLabel.frame.origin.x = newX
}
Thanks again for your response!
Solution 5
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
}
}
AdrianGutierrez
Updated on March 28, 2021Comments
-
AdrianGutierrez about 3 years
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!
-
AdrianGutierrez over 7 yearsIts a whole lot more code then i was expecting but it does work. I really hope Apple adds an easier way. Subtitle doesn't seem like anything that would be so far fetched.. lol
-
AdrianGutierrez over 7 yearsThanks a ton by the way! :) @rajan
-
cloudcal over 7 yearsGreat fix! Had to do this as well.
-
Ashu over 7 yearsI need something like this, If title is blank then title should in center. I have to implement in chat app. If user starts typing, then subtitle show. For more see whatsApp.
-
Nitish Makhija almost 7 yearstitle and subtitle slide to centre from left when pushing from navigation controller any workarounds
-
GerardoMR almost 7 yearsTo me, this is the cleaner answer, it doesn't have magic numbers as the first answer. I will only add
stackView.alignment = .center
after you set the axis, otherwise it will not appear totally centered if the subtitle is bigger. Also I would remove the last two calls tosizeToFit()
, since you called them on the labels. -
Zoom almost 7 yearstitle and subtitle slide to centre from left when pushing from navigation controller any workarounds @naveed
-
Naveed Ahmad almost 7 yearsabove solution work for centering the both text, in my case its working
-
Yasir almost 7 yearsHaving the same issue as @Zoom, from other posts it looks like it may be related to when in the view lifecycle the title is updated?
-
Zoom almost 7 years@Yasir adding the code for title and subtitle in viewDidAppear worked for me.
-
Yasir almost 7 yearsMy issue was fixed, keeping the initial update coming async from viewDidLoad. It was setting the titleView to an attributed label multiple times as the content changed during transition in. Got it working by only setting the view once, then only updating its contents if already present.
-
lemon lime pomelo over 6 yearsas per @GerardoMR comment above -- you can center title/subtitle using the UIStackView setting:
stackView.alignment = .center
-
Dilip Tiwari about 5 yearshow can i change alignment of both above to be left only
-
Dilip Tiwari about 5 yearsi tried titleLabel.textColor = UIColor.white but not working for me
-
user155 about 5 yearsdoes default title also has constant font value 17?