This is puzzling me for a while. This is my code:
let label:UILabel = UILabel(frame: CGRectMake(0, 0, obTextRect.width, obTextRect.height))
label.text = stText
label.backgroundColor = UIColor.redColor()
label.textAlignment = NSTextAlignment.Center
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByTruncatingTail
label.font = obDrawItem.m_obFont
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.1
label.layer.drawInContext(obContext)
CGContextRestoreGState(obContext)
and this is the result I am getting...
proceedin
g
The word "proceeding" does not "auto shrink" to fit the width.
Also if I add a line break (\n) then it works ok.
Any ideas???
The code works absolutely correctly. Why?
The text doesn't shrink because it fits into its frame.
The text doesn't use truncation because it fits into its frame.
Word wrapping is ignored because the word doesn't fit into single line.
I would advise you to set wrapping properties dynamically, depending on content. If the text has only one word, then set numberOfLines to 1, otherwise set it to 0 or 2-3. That will fix most of your problems.
let multipleWords = stText.rangeOfCharacterFromSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) != nil
label.numberOfLines = multipleWords ? 0 : 1
Try this:
label.numberOfLines = 1
Setting numberOfLines to 0 makes the label multi-line.
Related
I am trying to create a UILabel which contains two texts of different fonts where one NSMutableAttributedString sits vertically on top of the other. Upon attempting to insert a line break via swift's \n I found that the appended string disappears. I have tried a variety of lineBreakModes with no result (with and without \n) along with ensuring the frame isnt constricting the texts visibility by setting a large maximumLineHeight.
I should also mention that according to Apple's documentation when setting UILabel.attributedText to any NSAttributedText instance
When the label has an attributed string value, the system ignores the textColor, font, textAlignment, lineBreakMode, and lineBreakStrategy properties. Set the foregroundColor, font, alignment, lineBreakMode, and lineBreakStrategy properties in the attributed string instead.
Here is some of the code simplified for the sake of the question (I have also tried calling .sizeTofit() after setting the labels attributedText as well as setting different .lineBreakStrategys)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byWordWrapping
let totalVisitsString = NSMutableAttributedString(string: "\(visitLogs.count)\n", attributes: [.font : UIFont.systemFont(ofSize: 25), .paragraphStyle : paragraphStyle])
totalVisitsString.append(NSMutableAttributedString(string: "Total visits", attributes: [.font : UIFont.systemFont(ofSize: 14)]))
totalVisitsLabel.attributedText = totalVisitsString
the label itself:
var totalVisitsLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
By default your label's numberOfLines is 1. You never change it so that is what you get.
Labels when created are defaulted to 1 line. You'll need to set the number of lines to 0 (unlimited) or whatever number you want to max it at.
var totalVisitsLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
The problem I am facing is that UILabel will break line in the middle of the word although I am using word wrapping.
You can create a new project and replace content of view controller to see the result:
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
label.center = CGPoint(x: view.frame.midX, y: view.bounds.midY)
label.numberOfLines = 2 // Setting this to 1 produces expected result
label.lineBreakMode = .byWordWrapping
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.5
view.addSubview(label)
label.text = "Singlewordtext"
label.backgroundColor = .red
}
This produces 2 lines of text which is broken in the middle of the word. The reason this naturally happens is because the word itself is wider than the label itself so it makes sense (I guess). But I would hope that it would use adjustsFontSizeToFitWidth and minimumScaleFactor prior to breaking it. If I set it to single line (label.numberOfLines = 1) I get expected result which is that the text will shrink instead of break. Note that doing so in this case will fit all of the text inside the label.
The question is, is there a configuration on UILabel to prevent line break in such case? Or is there some other elegant solution?
A current result:
Desired result (produced by using label.numberOfLines = 1):
Do note that I still do need to have 2 lines enabled to nicely display for instance label.text = "Three words fit".
I'm trying to get my UILabel to get wider (along with its border and background color) as the content gets more - and then less when the content is reduced.
Where do I go to get started, I've looked at the Attributes Inspectors and it looks like this can only be done with code (which I'm fine with).
I thought adding two labels in a horizontal stack would do the trick, but it doesn't update in real-time (it will update the label only on launch).
Try using :
myLabel.sizeToFit()
on your label.This should update the label's frame to fit the content.
let label:UILabel = UILabel()
label.textColor=UIColor.black
label.font = UIFont(name: "Halvetica", size: 17)
label.numberOfLines = 1
label.text = "your string"
label.sizeToFit()
label.frame = CGRect(x: 5, y: imageView.frame.height+10, width: label.frame.width, height:label.frame.height)
I'm trying to make a label multilines, that fits the screen, so i'm using the CGFloat.max to make it's height dynamic... but using CGFloat.max is causing the label to ignore the positioning, any always keep on the position 0 in the Y axis....
Even passing any variable ou even a number to it, keeps on the 0 in Y axis
Any ideas to fix??
let label: UILabel = UILabel(frame: CGRectMake(10, 50, screenWidthArea, CGFloat.max))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.text = text
label.sizeToFit()
self.view.addSubview(label)
Actually I've changed CGFloat.max to 0 and it worked well... Still no idea for the reason CGFloat.max locks the label on the top of screen.
let label: UILabel = UILabel(frame: CGRectMake(10, 50, screenWidthArea, 0))
By selecting a Label in a StoryBoard, I can select Line Break to be Word Wrap and change number of lines to be more than 1. How can I do that Programmatically in Swift?
You can do this to set it programmatically
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.numberOfLines = 3
Swift 3/4
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 3
If you want the label to have multiple lines, do this:
var myLabel:UILabel = UILabel(frame: CGRectMake(7, 200, 370, 100))
myLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
myLabel.numberOfLines = 0 //'0' means infinite number of lines
Do remember to increase the height in "CGRectMake(7, 200, 370, 100)" <-- This
Otherwise the label won't be able to take the multiple lines of text.
Note with Swift 3 you need to use updated method byWordWrapping
productNameLabel.lineBreakMode = .byWordWrapping
productNameLabel.numberOfLines = 1
Or for adding Ellipsis at the end use byTruncatingTail
productNameLabel.lineBreakMode = .byTruncatingTail
productNameLabel.numberOfLines = 1