How to make Label first line text less from other line - ios

I want something like this, first line text should be wrap according to rating button width and rating button width may be less or greater.
If anyone have idea please give your answer.

AFAIK UILabel doesn't have such feature but you can achieve this behaviour by using UITextView. You can tweak it to look like your label and then set exclusion path for its' text container like this:
let exclusionPath = UIBezierPath(rect: textView.convert(button.frame, from: button.superview))
textView.textContainer.exclusionPaths = [exclusionPath]
If you also want to change button width according to the available width in the first line, then you can set excluded path frame with minimal width (according to text width and insets in button) and than calculate available space in first row similar to the way mentioned in this answer (it shows how to calculate the width of the last line but doing the same for the first one is quite similar)

Just try this codes, it will help you
myMutableString = NSMutableAttributedString(string: myString, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!])
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSRange(location:2,length:4))
myMutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "SFUIText-Bold", size: 14)!, range: NSRange(location:2,length:4))
labName.attributedText = myMutableString

Related

How to apply Atrributed String different spacing between lines in swift

I want to apply spacing between first two lines in attributed string and third line should look like paragraph.
Expected output :
Expected output screenshot
Current Implemenation:
Current implementaion screenshot
Here is the code tried by me.
let myString = "Your account phone numbers are listed here.\nTo change or delete a phone number, tap on it.\nTo add a phone number, go to the top right-hand corner of your screen and tap on “Add”.";
let font = UIFont.systemFont(ofSize: 14)
let attributedString = NSMutableAttributedString(string: myString, attributes: [.font: font])
self.displayLabel.attributedText = attributedString
I created label and setting number of lines 0 so it will display multiline text.
In the label need to show space in the first two lines as shown in expected output screenshot.
How to apply spacing only to first two lines and third line should display as shown in expected output screenshot?
You seem to want to set the spacing between paragraphs. This is controlled by NSParagraphStyle.paragraphSpacing. Just set the .paragraphStyle attribute of the attributed string to an NSParagraphStyle:
let paraStyle = NSMutableParagraphStyle()
paraStyle.paragraphSpacing = 10 // or some other number
let attributedString = NSMutableAttributedString(string: myString,
attributes: [
.font: font,
.paragraphStyle: paraStyle
])

NSAttributedString Drawing - How Many Lines?

I am drawing text within a PDF using this method:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byWordWrapping
let textAttributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: UIFont(name: "MySpecialFont", size: 16)!,
NSAttributedString.Key.foregroundColor: UIColor.black
]
let attributedText = NSAttributedString(
string: myTextArray.first,
attributes: textAttributes
)
let textRect = CGRect(
x: 400,
y: 40,
width: 80,
height: 40
)
attributedText.draw(in: textRect)
Above draws the text fine. However, sometimes, the string passed on to it seem to be too long and go on for 3 lines instead of 2. In these cases, I want to textRect to be taller. Basically to know how many lines it would take so textRect could be adjusted.
There are several functions within NSAttributedString that gives string length, but thats the length if it was in a single line.
Is there a way to know how many lines the final attributedText would take inside textRect?
Use NSAttributedString.boundingRect(with:options:context:) to compute the size required. You should pass .usesLineFragmentOrigin as an option so that it'll compute it for multiple lines. Pass the width you want; the height doesn't really matter, because it'll expand the height to contain the full string, and you can use that to work out your final rectangle.
That said, from your description, it sounds like you can just make the height very large (10,000 is the usual value; but maybe you want to just give room for three lines). Since you're just drawing here; it shouldn't matter if the available rect is taller than required. It only matters if it's shorter.

convert sketch line height into ios line 'height multiple' property

My designer send me sketch file which says 'Line height: 22' for label. How can i achieve this in xcode interface builder.
Is there any way to define this line height using code or UI builder.
#bbjay did put me on the right track.
If you want to obtain the exact result of Sketch, the formula is:
paragraphStyle .lineSpacing = sketchLineHeight - font.lineHeight
Provided that the font was given sketchFontSize
I've found the following formula to work well for me.
It converts form Sketch line height to iOS line spacing:
lineSpacing = sketchLineHeight - sketchFontSize - (font.lineHeight - font.pointSize)
In code, for your case this would be:
let font = UIFont.systemFont(ofSize: 18) // or whatever font you use
textLabel.font = font
let attributedString = NSMutableAttributedString(string: "your text")
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 22 - 18 - (font.lineHeight - font.pointSize)
attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedString.length))
textLabel.attributedText = attributedString
Line height is coming from CSS, so your designer must have a web designer background. On the mobile platforms, we do not specify line height, but line spacing.
In general NSMutableParagraphStyle offers capabilities to modify multiline labels for iOS.
NSMutableParagraphStyle has a property called maximumLineHeight, but this will only set the maximum line height to a certain value, if the containment of the label would exceed a certain value.
To set this up in IB, you need to add the label, and change the Text property to Attributed. Than click on paragraph style icon, and set the line spacing for the label. Looking at the design, it is around 2 points of line spacing, what you need. You can either ask your designer to provide you with line spacing attribute or try to find the right line spacing value by randomly trying out different values.
In storyboard, use the Atributed style of UILabel. Below is example with 2.5 line height

NSAttributedString with tabs

How do you create a UILabel with this kind of text format? Would you use NSAttributedString?
NSAttributedString can create text columns with tab stops. This is similar to how it is done in a word processor with the same limitations.
let text = "Name\t: Johny\nGender\t: Male\nAge\t: 25\nFavourites\t: Reading, writing"
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.tabStops = [NSTextTab(textAlignment: NSTextAlignment.Left, location: 150, options: [:])]
paragraphStyle.headIndent = 150
label.attributedText = NSAttributedString(string: text, attributes: [NSParagraphStyleAttributeName: paragraphStyle])
tabStops provides point positions for where to continue text after each tab. Here we did one tab at a reasonable point after the first column.
headIndent tells the label that wrapped text needs to be indented by a fixed amount, so it wraps to the next line.
The limitations with this approach are:
The tab stop location is a fixed point value so you need to know what you want. If the value you pick is less than the width of the first column for some lines, those lines will indent to a different location.
Wrapping only really works if your last column is the one that wraps. Since your second column was prefaced by ":" You may want to either just increase your headIndent or also split out the ":" to be \t:\t and set up a second tab stop. If you're not letting text wrap, this is not an issue.
If these limitations are too restrictive, you can restructure your label to be a collection of multiple labels with auto layout constraints.
In Swift 4.2 or above
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.tabStops = [NSTextTab.init(textAlignment: .left, location: 150, options: [:])]
paragraphStyle.headIndent = 150
let attributedTitle = NSAttributedString(string: "Some Title", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14.0), NSAttributedString.Key.paragraphStyle: paragraphStyle])

Can't get UILabel's text to stay on multiple lines

I have a UILabel that should display text on multiple lines in case that it's too long to stay on a single line. This how I set its parameters in interface builder:
But even by doing so, the text still gets truncated:
This is how I set the text at runtime:
let text = "left button pressed 5 seconds ago, you may want to press another button now"
let attributedText = NSMutableAttributedString(string: text)
attributedText.addAttribute(NSFontAttributeName, value: UIFont.boldSystemFontOfSize(statusLabel.font.pointSize), range: (text as NSString).rangeOfString("left"))
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .ByWordWrapping
attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedText.length))
statusLabel.attributedText = attributedText
Like you see I even tried to add a paragraph style attribute to force the text to stay on multiple lines, but it doesn't work.
Check that you're setting the auto layout constraints so you have the top, leading and trailing spaces defined, but don't hookup a vertical height, the label will adjust itself based on the content.
Edit:

Resources