Swift UILabel line spacing of break lines - swift

I have a text that comes from multiple sources and ends with \n\n for a line break in UILabel that has lines set to 0 through Storyboard.
For example:
let text = “Some text at the beginning of the paragraph that is this long\n\nSecond type of text\n\nSome longer text that is on later on in the paragraph”
The output is correct:
Some text at the beginning of the paragraph that is this long
Second type of text
Some longer text that is on later on in the paragraph
I have changed the line spacing to slightly increase the gaps between lines but can’t change the height of the empty line. I want the line break to be approximately half the size of a normal line break. I tried after/before paragraph settings but can’t get an empty line to be half the size.
Any idea if this is possible and what is the best way to achieve this through storyboard or programmatically.
----- Edit:
This is what I tried:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.paragraphSpacing = 0.1
paragraphStyle.paragraphSpacingBefore = 0.1
let attrString = NSMutableAttributedString(string: text)
attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
cell.firstLabel?.attributedText = attrString

Related

UILabel splitting in the middle of words (or how to get proper word wrapping)

I'm trying to fit some text into a fixed-width label (actually the width depends on the screen size, but cannot change within the app), and expect UIKit to cleverly use a combination of font resizing and word-wrapping to get the proper result. However, it doesn't seem to work that way. Considering a UILabel with the following constraints:
aspect ratio = 1:1
label.width = 0.7 * parentView.width (all other relevant constraints set, no errors or warnings in IB)
and the following code:
label.font = label.font.withSize(100)
label.adjustsFontSizeToFitWidth = true
label.lineBreakMode = .byClipping
label.numberOfLines = 0
label.text = "Shooter team"
I would be hoping that it would resize the text and make it fit into two lines: "Shooter" and "team" (or, since the text could be anything, split it properly into words). However, when I set label.lineBreakMode to .byWordWrapping, it doesn't resize the text at all and so only one big letter is displayed (note: I'm using a big font size for it to resize because I can't know in advance how big the text is going to be, since the size depends on the screen size). Any other value for .lineBreakMode results in the text being resized but split into "Shoote" and "r team", which looks dumb. Changing autoshrink to e.g. Minimum font size = 8 doesn't seem to have any effect. See screenshot below.
Any suggestion of how I can get the proper splitting/resizing? I may have used the wrong terms for my searches but I haven't found any answer :-|
(Note: there will be a different question about how I can get the border of the encompassing view to be a nice circle prior to the view being displayed :-| )
First, to take advantage of adjustsFontSizeToFitWidth, you must also give it a scale factor (the smallest size you're willing to let the label shrink to). So if, for example, your label's font is sized at 30, you could let it shrink down to 24:
someLabel.font = UIFont(name: "someFont", size: 30)
someLabel.adjustsFontSizeToFitWidth = true
someLabel.minimumScaleFactor = (24/30)
Second, you may want to consider using an attributed title for your label to take advantage of paragraph styling. Paragraph styling lets you play with hyphenation rules:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.hyphenationFactor = 1.0
let attributedTitle = NSAttributedString(string: "Shooter team", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red, NSAttributedString.Key.paragraphStyle: paragraphStyle])
someLabel.attributedText = attributedTitle
For lack of a better solution I've written the following function that empirically tries to find a font size that doesn't split a word in the middle. It's hackish but at least it works... Comments, suggestions or any better solution welcome!
func findFittingFont(for label: String) -> UIFont {
// note: the 'split' function is a personal addition that splits a string on a regex
// in this case, split between a non-word char and a word char
let words = label.split(pattern: "(?<=\\W)(?=\\w)")
var font = myLabel.font!
// the width we don't want to overflow
let maxWidth = myLabel.frame.width
var fontSize = myLabel.frame.height
var tooBig: Bool
repeat {
tooBig = false
font = font.withSize(fontSize)
// check for each word whether the rendered width is larger than the max width
for word in words {
// calculate the rendered width with the current font
let width = (word as NSString).size(withAttributes: [.font: font]).width
if width > maxWidth {
tooBig = true
// decrease the size by a factor
fontSize *= 0.9
break
}
}
// go on as long as there's an overflowing word
}
while tooBig
return font
}

Set height for a variable length message into a UIlabel in swift is not correct always

I wrote the following lines of code to set a variable length message into a UIlabel in swift, which works properly 9 out of 10 times. But at one time it suddenly truncated the last 2 or 3 lines from the message:
var response: AnyObject = prefs.objectForKey("response")!
response = response.stringByReplacingOccurrencesOfString("-", withString: "\n")
msglbl.numberOfLines = 0;
msglbl.text = "\(response)"
msglbl.textAlignment = .Center;
msglbl.sizeToFit()
self.view.addSubview(msglbl)
msglbl.font = UIFont(name: "Gotham-Book", size: 16)
Please let me know what I am doing wrong.
You are calling sizeToFit() before setting the label's font and size. Thus the label is being sized for the wrong font and size. Configure everything about the label first. Then size it to fit that configuration.

How to set UIButton titlelabel topdown

will like to know how to set the text in UIButton title Label in top down.
the text is "Press Me" across
will like to show
"
p
r
e
s
s
m
e
"
i did this
CGAffineTransform newTransform = CGAffineTransformMakeRotation(90 * (M_PI / 180));
self.activeButton.transform = newTransform;
but it only changed the button direction not the text
Rotating text to be vertical is different than writing each letter on a separate line, which is what I gathered to be your intention from your question.
To do that, you need to actually write each letter on a separate line! You can create new lines in UIButton text by holding Alt/Option while pressing enter in the text field in Interface Builder. Note that this has to be the text field property in the Utilities panel, you can't add new lines if you're editing the text by double clicking the button.
Once you've done this, change the "Line Break" mode to either Character Wrap or Word Wrap in order for it to display multiple lines.
Edit: I realised that you may be trying to work with your button in code, so I wrote this piece that should convert a regular button's text to be spaced vertically, letter by letter:
// Create a temporary NSString to store the new formatted text string
// Set it to the first character so we can have a simple loop from the second to the last character
NSString *newText = [NSString stringWithFormat:#"%C",[button.titleLabel.text characterAtIndex:0]];
for(int i=1;i<button.titleLabel.text.length;i++) {
// Format newText to include a newline and then the next character of the original string
newText = [NSString stringWithFormat:#"%#\n%C",newText,[button.titleLabel.text characterAtIndex:i]];
}
// We must change the word wrap mode of the button in order for text to display across multiple lines.
button.titleLabel.lineBreakMode = NSLineBreakByCharWrapping;
// .. and for an unknown reason, the text alignment needs to be reset. Replace this if you use something other than center alignment.
button.titleLabel.textAlignment = NSTextAlignmentCenter;
// newText now contains the properly formatted text string, so we can set this as the button label
[button setTitle:newText forState:UIControlStateNormal];

Use the second line of uiLabel if uilabel only have one line

In iOS project, I am creating an UILabel with 2 lines of text capacity, and i specified that the UILabel can content 2 lines. If the text only is 1 line, how can specify that the text is writing in the second line and the first be empty?
In other words, i would like that the text was writing in the UILabel from bottom to top.
Specifications:
The UILabel must be 2 lines maxium bigger.
If the text only needs 1 line of UILabel, the line which should be write is the second
If the text needs 2 lines, the UILabel should be completed first with the first line and then the second line.(normally. it works)
Thanks.
Use :
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;

how to make content of NSString goes to next line based on \n on iphone

i have a NSString s=#"hi\nhello\n\nwelcome to this world\ni m jhon"
now how to display this content in UIlabel so that \n allow 1 line gap and \n\n allows 2 line gap
still i am getting same value
NSString *s=aDl.content;// aDl.content=hi\nhello\n\nwelcome to this world\ni m jhon
labelb.text=s;// its same without line break :(
kindly help me
Thanks
Set label's height big enough to accommodate all lines in your string. Then set label's numberOfLines property to 0 - so label will draw its text in as much lines as required. New lines symbols (\n) will be handled by label automatically:
NSString *s=#"hi\nhello\n\nwelcome to this world\ni m jhon"
label.frame = ...//big enough height
label.numberOfLines = 0;
label.text = s;