Multiline Navigationbar Title - ios

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")

Related

How to change the text attribute of a UILabel in Swift?

I've set up a UILabel programmatically and I'm attempting to change the text attribute via a function I call later on in the ViewController however when that function is called the questionLabel.text stays the default value "Welcome".
Essentially what I'm trying to accomplish is:
func changeLabelText() {
questionLabel.text = "New label text"
print(questionLabel.text!)
}
changeLabelText()
// prints "New label text"
however what I'm actually getting is:
func changeLabelText() {
questionLabel.text = "New label text"
print(questionLabel.text!)
}
changeLabelText()
// prints "Welcome"
This is how my label is setup:
class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
#IBOutlet var cameraView: UIView!
var questionLabel: UILabel {
let label = UILabel()
label.lineBreakMode = .byWordWrapping
label.backgroundColor = .white
label.textColor = .black
label.text = "Welcome"
label.textAlignment = .center
label.frame = CGRect(x: 65, y: 100, width: 300, height: 65)
return label
}
Any suggestions? Greatly appreciated!
The current
var questionLabel: UILabel {
let label = UILabel()
label.lineBreakMode = .byWordWrapping
label.backgroundColor = .white
label.textColor = .black
label.text = "Welcome"
label.textAlignment = .center
label.frame = CGRect(x: 65, y: 100, width: 300, height: 65)
return label
}
is a computed property so every access gets a new separate instance
questionLabel.text = "New label text" // instance 1
print(questionLabel.text!) // instance 2
instead you need a closure
var questionLabel: UILabel = {
let label = UILabel()
label.lineBreakMode = .byWordWrapping
label.backgroundColor = .white
label.textColor = .black
label.text = "Welcome"
label.textAlignment = .center
label.frame = CGRect(x: 65, y: 100, width: 300, height: 65)
return label
}()
Change your computed variable to a lazy initializer like so:
lazy var questionLabel: UILabel = {
let label = UILabel()
label.lineBreakMode = .byWordWrapping
label.backgroundColor = .white
label.textColor = .black
label.text = "Welcome"
label.textAlignment = .center
label.frame = CGRect(x: 65, y: 100, width: 300, height: 65)
return label
}()
Klamont,
You can try this.
Suppose you want to change the some text of your label you always create two labels for that but it's a wrong approach of changing text color of label. You can use the NSMutableAttributedString for changing the some text color of your label.Firstly, you have to find the the range of text, which you want to change the color of that text and then set the range of your text to the NSMutableAttributedString object as compared to full string and then set your label attributedText with the NSMutableAttributedString object.
Example:
let strNumber: NSString = "Hello Test" as NSString // you must set your
let range = (strNumber).range(of: "Test")
let attribute = NSMutableAttributedString.init(string: strNumber)
attribute.addAttribute(NSForegroundColorAttributeName, value: UIColor.red , range: range)
yourLabel.attributedText = attribute
If you want to use this in many times in your application you can just create the extension of the UILabel and it will make more simple :-
extension UILabel {
func halfTextColorChange (fullText : String , changeText : String ) {
let strNumber: NSString = fullText as NSString
let range = (strNumber).range(of: changeText)
let attribute = NSMutableAttributedString.init(string: fullText)
attribute.addAttribute(NSForegroundColorAttributeName, value: UIColor.red , range: range)
self.attributedText = attribute
}
}
Use your label:-
yourLabel = "Hello Test"
yourLabel.halfTextColorChange(fullText: totalLabel.text!, changeText: "Test")

Setting UITableView's accessory view to a UILabel

I am trying to set the accessory view of a UITableView to a UILabel. I have tried looking around the Internet for an answer but could not find anything. Here is what I do:
let listCountLabel: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
label.text = "1"
label.layer.borderWidth = 2
label.layer.borderColor = UIColor.lightGray.cgColor
label.textColor = .lightGray
label.layer.cornerRadius = label.frame.height / 2
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont(name: "HelveticaNeue", size: 14)
label.textAlignment = .center
return label
}()
//Add to Subview
view.addSubview(listCountLabel)
cell.accessoryView = listCountLabel
There is no need to call view.addSubView(). Just call listCountLabel.sizeToFit() before inserting it into cell.accessoryView.
listCountLabel.sizeToFit()
cell.accessoryView = listCountLabel

Navigation set titleTextAttributes failed by swift3 , Xcode 8.3

I want my navigation title using TruncationMiddle like "ABC...XYZ" .
I try to do this, but I failed.
Thanks.
self.title = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byTruncatingMiddle
self.navigationController!.navigationBar.titleTextAttributes = [NSParagraphStyleAttributeName: paragraphStyle]
I got failed in my project
Link of my project in GitHub.
UPDATE IMAGE:
You actually need to use NSMutableParagraphStyle instead of NSParagraphStyle.
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byTruncatingMiddle
self.navigationController?.navigationBar.titleTextAttributes = [NSParagraphStyleAttributeName: paragraphStyle]
The lineBreakMode attribute then has a setter that you can use instead of setting the value directly with the key which is not allowed with the NSParagraphStyle class and the truncationMode key.
Try to add Custom Label in Navigation bar.
let label = UILabel(frame: CGRect(x:0, y:0, width:400, height:50))
label.backgroundColor = UIColor.clear
label.numberOfLines = 1
label.font = UIFont.boldSystemFont(ofSize: 13.0)
label.textAlignment = .center
label.textColor = UIColor.black
label.lineBreakMode = .truncateMiddle
self.navigationItem.titleView = label
// OR
// self.navigationController!.navigationBar.topItem.titleView = label
You can also show multiline in label if you want then just set numberOfLines to 0 and linebreak mode to worldwrap :)
Hope it is helpful
You just need to add following line into your code:
self.title = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
let navLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
navLabel.text = self.title
navLabel.textColor = .white
navLabel.font = UIFont(name: "Helvetica-Bold", size: 14.0)
navLabel.backgroundColor = .clear
navLabel.adjustsFontSizeToFitWidth = false
navLabel.lineBreakMode = .byTruncatingMiddle
self.navigationItem.titleView = navLabel

UILabel text truncation vs. line breaks in text

I have a UILabel that is put as titleView in the navigation bar. I want it to have 2 lines, where the first line can be truncated and the second is center aligned.
In code it looks more less like this:
let label = UILabel()
let text = NSAttributedString(string: "Long long long text\nsecond line")
label.attributedText = text
label.textAlignment = .Center
label.numberOfLines = 0
label.lineBreakMode = .ByTruncatingTail
label.sizeToFit()
self.navigationItem.titleView = label
The effect in case of the first line text is not exceeding available
space is like this:
It's pretty good, but when the first line text is longer than:
let text = NSAttributedString(string: "Very very very very very long text\nsecond line")
I want to achieve like below.
How it can be done? I experimented with numberOfLines and lineBreakMode but it's not worked.
change your line breakmode to ByTruncatingMiddle instead of ByTruncatingTail. Something like below,
label.lineBreakMode = .ByTruncatingMiddle
Hope this will help :)
Navigation Tittle with sub-Tittle (Multiline Navigation Tittle)
Use NSMutableAttributedString with UITextView instead of UILabel
(because, if tittle is large then UILabel lineBreakMode with .byTruncatingTail is not working for first line in UILabel)
func multilineNavigation(title:String,subTitle:String) {
DispatchQueue.main.async {
let titleAttributedStr = NSMutableAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor: UIColor.orange,NSAttributedStringKey.font: UIFont(name: "Helvetica Neue", size: 17.0) ?? UIFont()])
let subTitleAttributedStr = NSMutableAttributedString(string: "\n\(subTitle)", attributes: [NSAttributedStringKey.foregroundColor: UIColor.green,NSAttributedStringKey.font: UIFont(name: "Helvetica Neue", size: 12.0) ?? UIFont()])
titleAttributedStr.append(subTitleAttributedStr)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 1
paragraphStyle.lineBreakMode = .byTruncatingTail
titleAttributedStr.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, titleAttributedStr.length))
let textView = UITextView()
textView.attributedText = titleAttributedStr
textView.backgroundColor = .clear
textView.isUserInteractionEnabled = false
textView.textContainerInset = .zero
textView.textAlignment = .center
textView.frame = CGRect(x: 0, y: 0, width: textView.intrinsicContentSize.width, height: 44)
self.navigationItem.titleView = textView
}
}

swift - Can't find the numberOfLines attribute of UINavigationBar title text

I have used UINavigationBar.appearance() in swift. By using this, I have changed the backgroundColor and the textColor of UINavigationBarusing the below code.
However, I can't find the numberOfLinesattribute of the UINavigationBar title text. Any help on this is appreciated.
var naviAppreance = UINavigationBar.appearance()
naviAppreance.tintColor = uicolorFromHex(0xffffff)
naviAppreance.barTintColor = uicolorFromHex(0x00cc66)
naviAppreance.titleTextAttributes = [ NSForegroundColorAttributeName : UIColor.whiteColor()]
You have to design a custom view with a label and assign it as the titleView of your UINavigationBar
Example Swift Code:
var titleLabel = UILabel(frame: CGRectMake(0, 0, 480, 44))
titleLabel.backgroundColor = UIColor.clearColor()
titleLabel.numberOfLines = 2
titleLabel.shadowColor = UIColor(white: 0.0, alpha: 0.5)
titleLabel.textAlignment = UITextAlignmentCenter
titleLabel.font = UIFont.boldSystemFontOfSize(12.0)
titleLabel.textColor = UIColor.whiteColor()
titleLabel.text = "This is a\nmultiline string"
self.navigationItem.titleView = label

Resources