Justify Text in UILabel iOS - iphone

I am having a problem that in iOS I am using UILabel to display 2,3 line text, I want to align text as justified but I am not finding any option to do so. Any suggestions how to make justify text in label?
i put these line to make start it from top
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *textString = someString;
UIFont *textFont = [UIFont fontWithName:#"Futura" size:14];
CGSize textStringSize = [textString sizeWithFont:textFont
constrainedToSize:maximumSize
lineBreakMode:text.lineBreakMode];
CGRect textFrame = CGRectMake(10, 110, 300, textStringSize.height);
text.frame = textFrame;
so any trick like this to make it justfiy
Thanks

There is now a convenient way to justify text since iOS6. You can create an instance of NSAttributedString, set appropriate properties and assign this attributed string to a text representing view such as UILabel, UITextView, etc. It's easy as this:
Create an instance of NSMutableParagraphStyle and set its properties.
NSMutableParagraphStyle *paragraphStyles = [[NSMutableParagraphStyle alloc] init];
paragraphStyles.alignment = NSTextAlignmentJustified; //justified text
paragraphStyles.firstLineHeadIndent = 10.0; //must have a value to make it work
Create NSDictionary for text attributes and create attributed string.
NSDictionary *attributes = #{NSParagraphStyleAttributeName: paragraphStyles};
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: string attributes: attributes];
Set attributed string to a label.
existingLabel.attributedText = attributedString;

Can't be done I'm afraid - well not with UILabel.
You can use the UIWebView or a 3rd party library such as OHAttributedLabel
Happy Coding :)
Update:
This answer has been obsolete since iOS6. Please refer to Tankista's answer.

As mentionned by #martin, my class OHAttributedLabel can make this very easily.
(You will find it on my github and also find plenty of references to it on SO as well)

It can be done easily, but you need to use Core Text.
subclass a UIView, add an NSString property, create an NSAttributedString and pass kCTJustifiedTextAlignment value for the kCTParagraphStyleSpecifierAlignment key, then draw the NSAttributedString using Quartz or CoreText in your drawrect method.
edit: kCTParagraphStyleSpecifierAlignment key kCTJustifiedTextAlignment value should be used to create a CTParagraphStyleRef struct and passed in as a value for kCTParagraphStyleAttributeName key when creating the NSAttributedString.

SWIFT 4.x
version of approved answer:
Create an instance of NSMutableParagraphStyle and set its properties.
let justifiedParagraphStyles: NSMutableParagraphStyle = NSMutableParagraphStyle.init()
justifiedParagraphStyles.alignment = .justified //justified text
justifiedParagraphStyles.firstLineHeadIndent = 10.0 //must have a value to make it work
Create NSDictionary for text attributes and create attributed string.
let attributes = [NSAttributedStringKey.paragraphStyle: justifiedParagraphStyles]
let attributedString = NSAttributedString.init(string: string, attributes: attributes)
Set attributed string to a label.
existingLabel.attributedText = attributedString

Related

How to set Line Spacing in UI Text View (Empty text view) to enter message with line space

In my app i need to set some line spacing on ui text view..
I know we can do it for non editable textviews / labels using paragraph style spacing
But in my app when i enter text it was not working,
I can do it only when i have a predefined text on it, if once i clear the text paragraph sty will not work
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.minimumLineHeight = 35.f;
paragraphStyle.maximumLineHeight = 35.f;
UIFont *font = [UIFont fontWithName:#"AmericanTypewriter" size:18.f];
NSString *string = #"This is a test";
NSDictionary *attributtes = #{
NSParagraphStyleAttributeName : paragraphStyle,
};
deedTextView.font = font;
deedTextView.attributedText = [[NSAttributedString alloc] initWithString:string
attributes:attributtes];
But, I dont have any pre defined text like NSString *string = #"This is a test";
Text view must be empty, while begin
I had the same Problem. Based on Sergius answer I came up with the following working solution.
The problem with Sergius answer was that all other already set attributes will be overwritten (Font, Color...)
So it is better to edit the existing typingAttributes:
NSDictionary* d = deedTextView.typingAttributes;
NSMutableDictionary* md = [NSMutableDictionary dictionaryWithDictionary:d];
[md setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
deedTextView.typingAttributes= md;
One simple option that comes to mind is the following.
Using one of those 2 methods from UITextViewDelegate you can achieve what you want:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
- (void)textViewDidChange:(UITextView *)textView;
You algorithm is the following - take the textView.text, convert it to the style of your needs and set textView.text as textView.attributedText
You can also try setting this:
deedTextView.typingAttributes = [NSDictionary dictionaryWithObject:paragraphStyle forKey:NSParagraphStyleAttributeName];

How do I truncate a string within a string in a UILabel?

Say I have The Dark Knight Rises at 7:45pm and I need to fit that into a fixed-width UILabel (for iPhone). How would I make that truncate as "The Dark Knight Ris... at 7:45pm" rather than "The Dark Knight Rises at 7:4..."?
UILabel has this property:
#property(nonatomic) NSLineBreakMode lineBreakMode;
You enable that behaviour by setting it to NSLineBreakByTruncatingMiddle.
EDIT
I din't understand that you wanted to truncate only a part of the string.Then read this:
If you want to apply the line break mode to only a portion of the text, create a new attributed string with the desired style information and associate it with the label. If you are not using styled text, this property applies to the entire text string in the text property.
Example
So there is even a class for setting the paragraph style: NSParagraphStyle and it has also it's mutable version.
So let's say that you have a range where you want to apply that attribute:
NSRange range=NSMakeRange(i,j);
You have to create a NSMutableParagraphStyle object and set it's lineBreakMode to NSLineBreakByTruncatingMiddle.Notice that you may set also a lot of other parameters.So let's do that:
NSMutableParagraphStyle* style= [NSMutableParagraphStyle new];
style.lineBreakMode= NSLineBreakByTruncatingMiddle;
Then add that attribute for the attributedText of the label in that range.The attributedText property is a NSAttributedString, and not a NSMutableAttributedString, so you'll have to create a NSMutableAttributedString and assign it to that property:
NSMutableAttributedString* str=[[NSMutableAttributedString alloc]initWithString: self.label.text];
[str addAttribute: NSParagraphStyleAttributeName value: style range: range];
self.label.attributedText= str;
Notice that there are a lot of other properties for a NSAttributedString, check here.
You have to set the lineBreakMode. You can either do that from Interface Builder or programmatically as follows
label.lineBreakMode = NSLineBreakByTruncatingMiddle;
please note that since iOS 5 the type of such property changed from UILineBreakMode to NSLineBreakMode.
My first idea would be two labels side-by-side both with fixed width, but I'll assume you've ruled that out for some unstated reason. Alternatively, compute the truncation manually, like this ...
- (NSString *)truncatedStringFrom:(NSString *)string toFit:(UILabel *)label
atPixel:(CGFloat)pixel atPhrase:(NSString *)substring {
// truncate the part of string before substring until it fits pixel
// width in label
NSArray *components = [string componentsSeparatedByString:substring];
NSString *firstComponent = [components objectAtIndex:0];
CGSize size = [firstComponent sizeWithFont:label.font];
NSString *truncatedFirstComponent = firstComponent;
while (size.width > pixel) {
firstComponent = [firstComponent substringToIndex:[firstComponent length] - 1];
truncatedFirstComponent = [firstComponent stringByAppendingString:#"..."];
size = [truncatedFirstComponent sizeWithFont:label.font];
}
NSArray *newComponents = [NSArray arrayWithObjects:truncatedFirstComponent, [components lastObject], nil];
return [newComponents componentsJoinedByString:substring];
}
Call it like this:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 160, 21)];
NSString *string = #"The Dark Knight Rises at 7:45pm";
NSString *substring = #"at";
CGFloat pix = 120.0;
NSString *result = [self truncatedStringFrom:string toFit:label atPixel:120.0 atPhrase:#"at"];
label.text = result;
This generates: #"The Dark Kni...at 7:45pm"

Change UILabel color animated

How to change the color of the UILabel text gradually like the following link?
Can any one suggest me some code?
You can use formatted text.
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:#"Hello World"];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(1,5)];
iOS < 6
Second you need to subclass UILabel and print this string inside the drawRect method. You need to create a some type of loop that changes the color according to the speech speed.
iOS 6
You can use the attributedTextproperty (no need to subclass)
(void)drawTextInRect:(CGRect)rect
or reuse code:
https://github.com/mattt/TTTAttributedLabel
The app that you linked [http://www.youtube.com/watch?v=_vOYvaNhSHw] , probably is maded using cocos2d.
In cocos2d, you can change text color easily also with animation.
Here an example:
http://www.cocos2d-iphone.org/forum/topic/5903
Here cosos2d sdk, i suggest to try, because it's very powerful:
http://www.cocos2d-iphone.org/
enjoy.
here is one of my sample code. using block method of TTTAttributedLabel class it may help you .
[cell.lblAtt setText:strAtt afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
UIFont *italicSystemFont = [UIFont boldSystemFontOfSize:12];
CTFontRef italicFont = CTFontCreateWithName((__bridge CFStringRef)italicSystemFont.fontName, italicSystemFont.pointSize, NULL);
NSUInteger lenght = [[tempObj objectForKey:#"username"] length];
NSUInteger lenght2 = [[NSString stringWithFormat:#"%d",[tempArr count]] length];
[mutableAttributedString addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)[ThemeColor CGColor] range:NSMakeRange(0,lenght)];
[mutableAttributedString addAttribute:(NSString*)kCTFontAttributeName value:(__bridge UIFont*)italicFont range:NSMakeRange(0,lenght)];
[mutableAttributedString addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)[ThemeColor CGColor] range:NSMakeRange(lenght+11,lenght2)];
[mutableAttributedString addAttribute:(NSString*)kCTFontAttributeName value:(__bridge UIFont*)italicFont range:NSMakeRange(lenght+11,lenght2)];
return mutableAttributedString;
}];
Use NSAtributedString in UILabel from iOS 6.0. For lesser version below iOS 6.0 use TTTAttributedLabel which supports NSAtributedString
Change attributed string according to your requirement by setting it again in UILabel
EDIT add colored text as u want for example in loop
For 1st second in Label : I am good boy.
For 2nd second in Label : I am good boy.
For 3rd second in Label : I am good boy.
For 4th second in Label : I am good boy.
For 5th second in Label : I am good boy.

Get truncated text from UILabel

Is there anyway I can get the truncated version of the text for a UILabel?
In short, I have a paragraph of text, and two UILabels - label A, which is 2 lines long, and label B, which is a variable height. Label A is above label B. The idea is that label A shows the first two lines of the paragraph of text, and upon a certain user action, label B because visible and displays the rest of the text.
I'm having trouble determining what should go in label B, as I don't know what's being shown in label A. I'd need to also remove the "..." from label A.
Note: I realize this is a bit convoluted but there are some good reasons for it, which I won't clutter up the question with.
I wonder if you could use the methods in the NSString UIKit Additions to figure out how much fits into label A.
A crude way might be to start with the first character of your text and test for the size it would take up (-sizeWithFont:forWidth:lineBreakMode: maybe?) and then keep adding characters one at a time until it doesn't fit into your label A any more.
I hope somebody else can come up with a better way to do this, but the above should work.
Update
Last night I looked a bit into Core Text for my own app and came across CTFramesetterSuggestFrameSizeWithConstraints. You could maybe use this to figure out how much of your string fits into the label, by looking at the fitRange in that function.
Update 2:
I think this should work, but I have just typed this in here, so it may not even compile:
UIFont *uiFont = [UIFont systemFontOfZise:13.0f]; // whichever font you're using
CTFontRef ctFont = CTFontCreateWithName((CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);
NSDictionary *attr = [NSDictionary dictionaryWithObject:(id)ctFont forKey:(id)kCTFontAttributeName];
CFRelease(ctfont);
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:yourLabelText attributes:attr];
CTFrameSetterRef frameSetter = CTFrameSetterCreateWithAttributedString((CFAttributedStringRef)attrString);
[attrString release];
CFRange fitRange;
CTFrameSetterSuggestFrameSizeWithConstrains(
frameSetter,
CFRangeMake(0, 0),
NULL,
CGSizeMake(labelWidth, labelHeight),
&fitRange);
CFRelease(frameSetter);
CFIndex numberOfCharactersThatFit = fitRange.length;
thanks to Thomas Müller
be sure to set line break mode the myLabel to this:
myLabel.lineBreakMode = NSLineBreakByWordWrapping;
by this method you can get chunked strings that actually fit in the constrained size.
Here is the baked code:
- (NSArray *)truncate:(NSString *)text
{
NSMutableArray *textChunks = [[NSMutableArray alloc] init];
NSString *chunk = [[NSString alloc] init];
CTFramesetterRef frameSetter;
UIFont *uiFont = [UIFont systemFontOfSize:17.0f];
CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);
NSDictionary *attr = [NSDictionary dictionaryWithObject:(__bridge id)ctFont forKey:(id)kCTFontAttributeName];
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:text attributes:attr];
CFRange fitRange;
while (attrString.length>0) {
frameSetter = CTFramesetterCreateWithAttributedString ((__bridge CFAttributedStringRef) attrString);
CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, CFRangeMake(0,0), NULL, CGSizeMake(myLabel.frame.size.width, myLabel.frame.size.height), &fitRange);
CFRelease(frameSetter);
chunk = [[attrString attributedSubstringFromRange:NSMakeRange(0, fitRange.length)] string];
[textChunks addObject:chunk];
[attrString setAttributedString: [attrString attributedSubstringFromRange:NSMakeRange(fitRange.length, attrString.string.length-fitRange.length)]];
}
return textChunks;
}
For Label A, calculate approximate character that should fit perfectly for two lines, for the particular font you are using.
For label B, set variable Height that the whole text must fit into it.

IPhone: Change line spacing in UITextView?

I've been looking all over the 'net for information/examples...
I'm trying to change the line spacing of text inside a UITextView object to double spaced. I thought you could do it via Core Text, but haven't found a solution!
Any example code or information would be greatly appreciated! Thanks!
You don't have to look all over the net. A look at the documentation for UITextView is sufficient to determine that changing the line spacing is not supported by that control.
With Core Text you have complete control over the layout of the text you draw, of course. But it would be a lot of work to rewrite a UITextView-like control from scratch.
This question was asked before iOS 6. I'd like to post an updated answer for those who would like a way to do this.
This can be done now with iOS 6 and later by using an NSAttributedString. UITextView now accepts an attributed string as one of its properties. You can do all sorts of text manipulation with attributed strings, including line spacing. You can set the min and max line heights for the paragraph style attribute of the string.
Check out the NSAttributedString Class Reference for more information.
Here's a sample of what you could do:
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.minimumLineHeight = 21.0f;
paragraph.maximumLineHeight = 21.0f;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:#"Test text line 1\nTest text line 2\nTest text line 3" attributes:#{NSParagraphStyleAttributeName: paragraph}];
textView.attributedText = attributedString;
You can use NSLayoutManagerDelegate. Add that delegate to your ViewController or UIView class (etc.) and then when you create your UITextView...
yourTextView.layoutManager.delegate = self
Add this delegate method:
func layoutManager(layoutManager: NSLayoutManager, lineSpacingAfterGlyphAtIndex glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat {
return 5 //Whatever you'd like...
}