Swift 3 UILabel, how to word wrap after changing text - ios

I have a UILabel which has been created programmatically and want to set the text property dynamically after its creation. I can word wrap it during init but not subsequently. After the title label text is changed it keeps one line, regardless of whether I set the number of lines to 2 or 0 and word wrap or not. After I change the title I want it to occupy 2 lines and the text is easily long enough for this to happen but it does not.
let titleLabel: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .clear
label.layer.masksToBounds = true
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.textColor = .white
return label
}()
var titleLabelText: String? {
didSet {
titleLabel.text = titleLabelText
titleLabel.layoutIfNeeded()
}
}
then later...
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
titleLabelText = "some string which needs word wrapping"
}
titleLabel.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
titleLabel.widthAnchor.constraint(equalToConstant: screenWidth - 90).isActive = true
Font size is UIFont(name: "Muli", size: 12)
Here is how I load my label in viewDidLoad() but the label.text is applied in viewDidAppear()
let headerStackView: UIStackView = {
let headerArray = [welcomeLabel]
let stackView = UIStackView(arrangedSubviews: headerArray)

When you set your label to display multiple line..Remember your label must have enough height that can hold your text to be display multiple line.
Try to increase height of your label, Check width is proper and then check with your code.

If your text gets increases decrease the font size, it will automatically show complete text in your label.
and set the label line space to 0 and allow word wrap property true

select your label and try this one

AFAIK You need to add it as attributedText, then create an NSAttributedString, with your string and attributes.
let paragraphStyleWithWordWrapping = NSMutableParagraphStyle()
paragraphStyleWithWordWrapping.lineBreakMode = .byWordWrapping
let attributedString = NSAttributedString(myString, [NSParagraphStyleAttributeName: paragraphStyleWithWordWrapping])
label.attributedText = attributedString

Related

How to convert Navbar Large title to Multi-line, centre aligned

I'm trying to design view controller with Multi-lined centred Large title text exactly like Ask Siri by apple (Settings->General->Keyboards->About Ask Siri, Dictation and Privacy...).
I can able to achieve centred text using:
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
navigationController?.navigationBar.largeTitleTextAttributes = [.paragraphStyle: paragraph]
I did set Navigation title from Storyboard and tried these to achieve multi-lined large title:
https://stackoverflow.com/a/51295457/4061501
https://stackoverflow.com/a/48388588/4061501
But none of them are worked on iOS 13.
You can achieve this by adding a multiline label to your scrollView and then show/hide your navigation item title in the scrollViewDidScroll delegate method of the scrollView depending on the vertical scrollView offset.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y > myLabelHeight && navigationItem.title == "" {
setTitle(hidden: false)
} else if scrollView.contentOffset.y <= myLabelHeight && navigationItem.title == "MyTitleString" {
setTitle(hidden: true)
}
}
I've added a layer transition to achieve the fade effect.
func setTitle(hidden: Bool) {
let animation = CATransition()
animation.duration = 0.25
animation.type = .fade
navigationController?.navigationBar.layer.add(animation, forKey: "fadeText")
if hidden {
navigationItem.title = ""
} else {
navigationItem.title = "MyTitleString"
}
}
Don't forget to set the navigation item title to an empty string in viewDidLoad.
There is not any such kind of property that you can set and title became multiline. You need to manipulate it.
This is a code example of how you can create a multiline navigationBar title:
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```

How can you find the height of a label that is "sizeToFit"?

I have a label containing strings of variable size. The label is embedded in a vertical stack of a fixed width.
var productName: UILabel = {
let lbl = UILabel()
lbl.translatesAutoresizingMaskIntoConstraints = false
lbl.numberOfLines = 0
lbl.sizeToFit()
lbl.textColor = .black
lbl.font = UIFont(name: "HelveticaNeue", size: 13)
lbl.textAlignment = .center
return lbl
}()
var Vstack: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.alignment = .center
return stack
}()
I need the height of this label after inserting text into it because it dictates the size of a tableViewCell it is in. As the string it contains is variable and the label itself is "sizeToFit", I have been unable to calculate its height with the first things that came to mind:
productName.frame.height
productName.frame.size.height
productName.layer.frame.height
Is there any way to get the height of a label after inserting text into it?
You can use intrinsicContentSize which returns the CGSize of the label text the UILabel element,
You can read more about it in this article: intrinsicContentSize

UILabel text alignment not working (Swift 4)

I'm trying to align the text in a UILabel but it's not working. The text prints with the second line of the label hugging the left side of the label. How do I make both lines aligned in the center of the label? Thanks.
let bioTextView: UILabel = {
let tv = UILabel()
tv.text = "This is sample text for a bio label for a user on this platform."
tv.backgroundColor = .clear
tv.textColor = .white
tv.lineBreakMode = .byWordWrapping
tv.numberOfLines = 0
tv.textAlignment = NSTextAlignment.right
return tv
}()
Please find the below screenshot for the issue. My requirement is to fit the text in tow lines.
Try setting the alignment after you have added the view as a subview.
view.addSubview(self.bioTextView)
bioTextView.textAlignment = .center
Try this one:
let bioTextView: UILabel = {
let tv = UILabel()
tv.backgroundColor = .clear
tv.textColor = .white
tv.lineBreakMode = .byWordWrapping
tv.numberOfLines = 0
let textString = NSMutableAttributedString(
string: "This is sample text for a bio label for a user on this platform.",
attributes: [:])
let textRange = NSRange(location: 0, length: textString.length)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
textString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: textRange)
tv.attributedText = textString
return tv
}()
If someone is using UIStackView and has encountered this problem: stackView.alignment can ruin label.textAlignment property. Simply remove stackView.alignment.
Update following line fo code will fix your issue:
tv.textAlignment = .center
This will align your label text to center.

How to truncate UILabel to show '...' at the end of the string

I have a UILabel() i am trying to truncate.
let nameLabel: UILabel = {
let label = UILabel()
label.textColor = .black
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 11)
label.numberOfLines = 0
//label.lineBreakMode = .byTruncatingTail
//label.adjustsFontSizeToFitWidth = false
label.textAlignment = .center
label.sizeToFit()
return label
}()
here are my constraints:
nameLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
nameLabel.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -10).isActive = true
nameLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 8).isActive = true
The issue that i am having is that the actual string gets truncated but instead of having the string 'Johnson Rodriguez' truncate to ''Johnson Rod...'' it ends up cropping out anything after the space, resulting in the label displaying 'Johnson'
These are the things i have tried using:
label.lineBreakMode = .byTruncatingTail
label.sizeToFit()
label.preferredMaxLayoutWidth = 70
This is what i have seen other people use but for some reason i cant get it to display the ... instead of truncating the string at the first space.
Setting numberOfLines to 1 should do the trick for you.
From the docs:
This property controls the maximum number of lines to use in order to fit the label’s text into its bounding rectangle. The default value for this property is 1. To remove any maximum limit, and use as many lines as needed, set the value of this property to 0.

Swift/Cocoa Touch: How do I centre dynamically resized text in a UILabel?

I have a UILabel that takes the size of its parent view.
I want the label text to resize to fit within the containing view.
override func draw(_ rect: CGRect) {
let fontSize = self.frame.size.height * 0.9
var font = UIFont.preferredFont(forTextStyle: .body).withSize(fontSize)
font = UIFontMetrics(forTextStyle: .body).scaledFont(for: font)
let label = UILabel()
label.textAlignment = .center
label.font = font
label.frame.size = self.frame.size
label.minimumScaleFactor = 0.1
label.numberOfLines = 1
label.adjustsFontSizeToFitWidth = true
label.text = "5"
addSubview(label)
}
The above works just how I want. The number 5 is displayed in the centre of the containing view. However if I set the text to something longer (for example: label.text = "5"), its vertical position changes.
How do I ensure that, no matter the length of the string, the text will be centred vertically as well as horizontally.
Add this line of code in your UILabel set up. Should work as expected. This will make the label to center vertically.
label.baselineAdjustment = .alignCenters

Resources