Use large navigation title and fit text - ios

I have issue with navigation bar title. First of all I am using large titles with:
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
Is it possible to have a large title with resizable fonts?

There is one property called largeTitleTextAttributes. I think it will solve your problem.
Write the following code in view controller's viewDidLoad method.
self.navigationItem.largeTitleDisplayMode = .always
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 100)]

You have to resize your title view. Try this
self.title = "Your TiTle Text"
let tlabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
tlabel.text = self.title
tlabel.textColor = UIColor.white
tlabel.font = UIFont(name: "Helvetica-Bold", size: 30.0)
tlabel.backgroundColor = UIColor.clear
tlabel.adjustsFontSizeToFitWidth = true
tlabel.textAlignment = .center;
self.navigationItem.titleView = tlabel

Related

How to reduce the left and right gaps in custom view for Navigation bar in iOS

I recently added a side menu which is having a UITableviewController class as the Menu . In this ViewController i added a custom view to the Navbar through this code. But when i run in device i get extra space on left and right side of the view . How to remove this?
import UIKit
class SettingsTableController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let newView = UIView()
newView.frame = CGRect(x:UIApplication.shared.statusBarFrame.origin.x,y:UIApplication.shared.statusBarFrame.height, width: view.frame.size.width + 10, height: self.navigationController!.navigationBar.frame.height)
//#710193
newView.backgroundColor = UIColor.red
let lblTitle = UILabel()
lblTitle.text = " Animals"
lblTitle.textColor = UIColor.white
lblTitle.font = UIFont(name: "HelveticaNeue-Bold", size: 18.0)
lblTitle.frame = newView.bounds
newView.addSubview(lblTitle)
navigationItem.titleView = newView
}
}
so it produces the output as below. I want to remove the pointed out gaps which is shown through red arrows .
You are setting frame but also need to autolayout. So after newView.addSubview(lblTitle) add below codes.
newView.translatesAutoresizingMaskIntoConstraints = false
newView.layoutIfNeeded()
newView.sizeToFit()
newView.translatesAutoresizingMaskIntoConstraints = true
navigationItem.titleView = newView
I have changed some line of code in your code and it is working fine for me
let newView = UIView()
newView.frame = CGRect(x:UIApplication.shared.statusBarFrame.origin.x,y:UIApplication.shared.statusBarFrame.height, width: view.frame.size.width, height: self.navigationController!.navigationBar.frame.height)
//#710193
newView.backgroundColor = UIColor.red
let lblTitle = UILabel()
lblTitle.text = " Animals"
lblTitle.textColor = UIColor.white
lblTitle.font = UIFont(name: "HelveticaNeue-Bold", size: 18.0)
lblTitle.frame = newView.bounds
newView.addSubview(lblTitle)
You are adding newView to titleView of navigationItem instead of adding that to navigationBar of navigationController
self.navigationController?.navigationBar.addSubview(newView)
Try to use auto layout constraint programatically in swift. The link is provided below
Auto Layout in Swift: Writing constraints programmatically

Dynamically resize navigation bar title during Large Titles mode

How do I dynamically resize my navigation bar title while in iOS 11's Large Title mode?
Previously you could define your own UILabel as the titleView and have it resize. All it does now is add another titleView on top.
override func viewDidLoad() {
super.viewDidLoad()
self.title = "A very long title. Really long. Dont truncate me though. I want everyone to see me."
let frame = CGRect(x: 0, y: 0, width: 200, height: 40)
let tlabel = UILabel(frame: frame)
tlabel.text = self.title
tlabel.textColor = UIColor.black
tlabel.font = UIFont.boldSystemFont(ofSize: 17)
tlabel.backgroundColor = UIColor.clear
tlabel.adjustsFontSizeToFitWidth = true
tlabel.textAlignment = .center
self.navigationItem.titleView = tlabel
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .automatic
}

How to make iOS navigationItem.titleView align to the left?

navigationItem.hidesBackButton = true
navigationItem.leftBarButtonItem = nil
head = UIView()
head.frame = CGRectMake(0, 0, 200, 44)
head.frame.origin.x = CGFloat(0)
navigationItem.titleView = head
I attempt to align the titleView to the left, but it still remains in the middle.
Try this:
let title = UILabel()
title.text = "TITLE"
let spacer = UIView()
let constraint = spacer.widthAnchor.constraint(greaterThanOrEqualToConstant: CGFloat.greatestFiniteMagnitude)
constraint.isActive = true
constraint.priority = .defaultLow
let stack = UIStackView(arrangedSubviews: [title, spacer])
stack.axis = .horizontal
navigationItem.titleView = stack
The idea is that main view (in this case title) will take all the space it needs and spacer view will take all the free space left.
I figured it out.
I just need to set my custom UIView as the leftBarButtonItem.
I had a similar requirement of adding the Title along with the subtitle to the left of the navbar. I couldn't achieve it with a TitleView since it cannot be aligned left.
So I took #TIMEZ and #Wain's answers, along with responses from the thread here and added a complete answer, in case it helps anyone :
let titleLabel = UILabel()
titleLabel.text = "Pillars"
titleLabel.textAlignment = .center
titleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.headline)
let subtitleLabel = UILabel()
subtitleLabel.text = "How did you do today?"
subtitleLabel.textAlignment = .center
subtitleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.subheadline)
let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
stackView.distribution = .equalSpacing
stackView.alignment = .leading
stackView.axis = .vertical
let customTitles = UIBarButtonItem.init(customView: stackView)
self.navigationItem.leftBarButtonItems = [customTitles]
You can't align a title view to the left. You can create a title view and add a subview positioned to its left. If you're looking to display in place of the back button then you should be using a bar button item instead of title view.
I don't think Apple wants you to do that. Navigation bars have a pretty specific purpose that often involves having something else in the top left corner like a Back button. You might be better off making a custom UIView or UIToolbar that looks like the navigation bar.
If it's a custom UIView, override intrinsicContentSize and return
CGSize(width: .greatestFiniteMagnitude, height: UIView.noIntrinsicMetric)
This will stretch the view to the entire width between left and right bar button items.
You can constraint the titleView to the navigationBars leftAnchor.
private func setupNavigationBarTitleView() {
let titleView = YourCustomTitleView()
navigationBarTitleView = titleView
navigationBarTitleView?.translatesAutoresizingMaskIntoConstraints = false
navigationItem.titleView = navigationBarTitleView
if let navigationBar = navigationController?.navigationBar {
NSLayoutConstraint.activate([
titleView.leadingAnchor.constraint(equalTo: navigationBar.leadingAnchor, constant: 16),
titleView.heightAnchor.constraint(equalToConstant: 36)
])
}
}
The simplest solution is to add low priority constraint for title width.
let titleLabel = UILabel()
titleLabel.textAlignment = .left
...
let c = titleLabe.widthAnchor.constraint(equalToConstant: 10000)
c.priority = .required - 1
c.isActive = true
navigationItem.titleView = titleLabel
Hey guys after trying most of the solutions above. I found that most of em still did not meet my prod requirements. Here is a solution I came up with after trying out different solutions.
func setLeftAlignTitleView(font: UIFont, text: String, textColor: UIColor) {
guard let navFrame = navigationController?.navigationBar.frame else{
return
}
let parentView = UIView(frame: CGRect(x: 0, y: 0, width: navFrame.width*3, height: navFrame.height))
self.navigationItem.titleView = parentView
let label = UILabel(frame: .init(x: parentView.frame.minX, y: parentView.frame.minY, width: parentView.frame.width, height: parentView.frame.height))
label.backgroundColor = .clear
label.numberOfLines = 2
label.font = font
label.textAlignment = .left
label.textColor = textColor
label.text = text
parentView.addSubview(label)
}
let navLabel = UILabel(frame: CGRect(x: 0, y: 0, width: view.frame.width - 32, height: view.frame.height))
navLabel.text = "Hi, \(CurrentUser.firstName)"
navLabel.textColor = UIColor.white
navLabel.font = UIFont.systemFont(ofSize: 20)
navigationItem.titleView = navLabel

Multiline Navigationbar Title

I am trying to set the title label in my navigation bar to allow multiple lines. I have custom navigation controller code that I am placing the multiline code into. I know that the code already there works, but my multiline part is not working.
let titleLabel = UILabel()
titleLabel.frame = CGRectMake(0, 0, self.navigationBar.frame.width, self.navigationBar.frame.height * 2)
titleLabel.numberOfLines = 0
titleLabel.lineBreakMode = .ByWordWrapping
navigationItem.titleView = titleLabel
But the text still runs off at the end. I've also tried putting this into the individual view controller itself, adding self.navigationController?. in front of navigationItem with the same results.
Is there something I'm missing in my code that would keep the title label from using multiple lines?
Here is a code example of how you can create a multiline navigationBar title
let label: UILabel = UILabel(frame: CGRectMake(0, 0, 400, 50))
label.backgroundColor = UIColor.clearColor()
label.numberOfLines = 2
label.font = UIFont.boldSystemFontOfSize(16.0)
label.textAlignment = .Center
label.textColor = UIColor.whiteColor()
label.text = "This is a\nmultiline string for the navBar"
self.navigationItem.titleView = label
Swift 5.x:
let label = UILabel()
label.backgroundColor = .clear
label.numberOfLines = 2
label.font = UIFont.boldSystemFont(ofSize: 16.0)
label.textAlignment = .center
label.textColor = .white
label.text = "This is a\nmultiline string for the navBar"
self.navigationItem.titleView = label
This is doable in a storyboard. Just drag a UIView into the Navigation bar, then drag a UILabel onto it in the document outline, set lines to 2 and alignment to center.
Use this to get the label position exactly as you want it:
let labelWidth = navBar.bounds.width - 110
let label = UILabel(frame: CGRect(x:(navBar.bounds.width/2) - (labelWidth/2), y:0, width:labelWidth, height:navBar.bounds.height))
label.backgroundColor = UIColor.clear
label.numberOfLines = 0
label.font = UIFont.boldSystemFont(ofSize: 13.0)
label.textAlignment = .center
label.textColor = UIColor.black
label.lineBreakMode = .byWordWrapping
label.text = loadedName
navBar.topItem?.title = nil
navBar.addSubview(label)
the 110 value in the top line is the spacing you want either side of the label.
swift 5+ very easy solution
func titleMultiLine(topText: String, bottomText: String) {
// let titleParameters = [NSForegroundColorAttributeName : UIColor.white,
// NSFontAttributeName : UIFont.<Font>]
// let subtitleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
// NSFontAttributeName : UIFont.<Font>]
let titleParameters = [NSAttributedString.Key.foregroundColor : UIColor.white]
let subtitleParameters = [NSAttributedString.Key.foregroundColor : UIColor.white]
let title:NSMutableAttributedString = NSMutableAttributedString(string: topText, attributes: titleParameters)
let subtitle:NSAttributedString = NSAttributedString(string: bottomText, attributes: subtitleParameters)
title.append(NSAttributedString(string: "\n"))
title.append(subtitle)
let size = title.size()
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
titleLabel.attributedText = title
titleLabel.numberOfLines = 0
titleLabel.textAlignment = .center
navigationItem.titleView = titleLabel
}
Function Calling
self.titleMultiLine(topText: "I am top text Title", bottomText: "bottom text")

Swift: ViewController Title Size in Code?

I have a ViewController.
I added a Title to the Viewcontroller.
Its a variable.
var Title: String! = "🎯"
override func viewDidLoad() {
super.viewDidLoad()
self.title = Title
}
Is there a way, to make the font bigger?
This way you can customise your navigation title:
self.title = "🎯"
var attributes = [NSFontAttributeName: UIFont(name: "Avenir", size: 20)!] //change size as per your need here.
self.navigationController?.navigationBar.titleTextAttributes = attributes
Make a Title View Label and assign it to the navigation item.
code for it is:
var tlabel = UILabel(frame: CGRectMake(0, 0, 300, 40))
tlabel.text = self.navigationItem.title;
tlabel.textColor = UIColor.whiteColor()
tlabel.backgroundColor = UIColor.whiteColor()
tlabel.adjustsFontSizeToFitWidth = true
self.navigationItem.titleView = tlabel
Here is the possible work around. You can assign any UIView to a navcontroller's title area.
Create a UILabel and set its font and size anyway you want, then assign it to the UIViewController's navigationItem.titleView property. Make sure the UILabel's backgroundColor is set to clearColor.
UILabel *labelTitle = UILabel(frame: CGRectZero);
labelTitle.text = "Title";
labelTitle.font = UIFont(name: "Your-Font-Name", size: SIZE)
labelTitle.text.textAlignment = NSTextAlignment.Center
self.navigationItem.titleView = labelTitle;

Resources