Autofit label, CGSize gives value zero - iphone

I want to change the size of a label depending on how big it is. I set a breakpoint on the first line, and as I go down I see that "tagsSize" actually has a value when I get to the line that starts with CGSize, it is then changed to zero after that line. I actually used this same code, with changes of course, in a different class of the same project and it is working fine. I am probably looking over something. Please take a look and let me know what I am doing wrong.
_tagsArray = [[NSMutableArray alloc] initWithObjects:#"Astronaut", #"iPhone", #"iOS", #"Software Engineer", #"Carpentry", #"Landscape Design", #"Doctor", #"Actor", #"CEO", #"iOS Developer", #"Software Engineer", #"Carpentry", #"Landscape Design", #"Doctor", #"Actor", #"CEO", #"iOS Developer", nil];
_tagsString = [_tagsArray componentsJoinedByString:#", "];
_tagsLbl.font = [UIFont fontWithName:#"Helvetica" size:18];
CGSize tagsSize = [_tagsString sizeWithFont:[_tagsLbl font]];
NSLog(#"%f", tagsSize.width);
CGFloat tagsWidth = tagsSize.width;

Where do you alloc the UILabel? I think it is nil when you use it..

try this:
CGSize size = [string sizeWithFont:[UIFont boldSystemFontOfSize:fontb]
constrainedToSize:CGSizeMake(TEXTLABEL_WIDTH, 1000)
lineBreakMode:UILineBreakModeCharacterWrap];

Related

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.

Label Text is not wrapped

I assign a label in a table view but the text in the label does not wrap to the next line when it is too long.
My code is follow:
UILabel *food_lbl=[[UILabel alloc]init];
foodspe = [NSString stringWithFormat:#"%#",[[NSUserDefaults standardUserDefaults]valueForKey:#"food"]];
foodspe = [foodspe stringByReplacingOccurrencesOfString:#"(" withString:#""];
foodspe = [foodspe stringByReplacingOccurrencesOfString:#")" withString:#""];
foodspe = [foodspe stringByReplacingOccurrencesOfString:#"\n" withString:#""];
foodspe = [foodspe stringByReplacingOccurrencesOfString:#" " withString:#""];
food_lbl.text = foodspe;
food_lbl.numberOfLines=2;
food_lbl.lineBreakMode=UILineBreakModeWordWrap;
[food_lbl setFrame:CGRectMake(100, 0, 150, 100)];
[food_lbl setFont:[UIFont boldSystemFontOfSize:25.0f]];
[cell.contentView addSubview:header];
e.g. food_lbl is paneer,panjabi,pasta,pizza,Puff,chocolates
Have you tried this ?
food_lbl.numberOfLines=0;
Go to the UILabel property in the xib and make Autoshrink YES.
I'll suggest two options,
Use this method to find the required height for your text label and
set it to that:
CGFloat height = [foodspe sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(food_lbl.frame.size.width, 500) lineBreakMode:UILineBreakModeWordWrap].height;
Add a space between each word of your input text. That is change this paneer,panjabi,pasta,pizza,Puff,chocolates to paneer, panjabi, pasta, pizza, Puff, chocolates
if your listed code (shown below) was used exactly in your project, then you are adding a wrong label.
UILabel *food_lbl=[[UILabel alloc]init];
...
[cell.contentView addSubview:header];
You are adding header rather than the newly created food_lbl.

UIFont fontWithName font name

Say you want a specific font for UIFont.
How do you know what it's called?
E.g. if you wanted to use this code:
[someUILabelObject setFont:[UIFont fontWithName:#"American Typewriter" size:18]];
From where do you copy the exact phrase "American Typewriter". Is there a header file in Xcode?
UPDATE
Also found this handy.
Might be interesting for you as Quick Win within the Debugger:
(lldb) po [UIFont fontNamesForFamilyName:#"Helvetica Neue"]
(id) $1 = 0x079d8670 <__NSCFArray 0x79d8670>(
HelveticaNeue-Bold,
HelveticaNeue-CondensedBlack,
HelveticaNeue-Medium,
HelveticaNeue,
HelveticaNeue-Light,
HelveticaNeue-CondensedBold,
HelveticaNeue-LightItalic,
HelveticaNeue-UltraLightItalic,
HelveticaNeue-UltraLight,
HelveticaNeue-BoldItalic,
HelveticaNeue-Italic
)
November 2018 - Update
A new swift-y reference for "Custom Fonts with Xcode" - by Chris Ching. I had to update, as this is a great value posting for the new way combined with all missing parts to use custom fonts in a project.
The documentation for UIFont is pretty clear on this:
You can use the fontNamesForFamilyName: method to retrieve the
specific font names for a given font family.
(Note: It is a class method)
You can get the family names like this:
NSArray *familyNames = [UIFont familyNames];
Try
NSArray *familyNames = [UIFont familyNames];
[familyNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
NSLog(#"* %#",obj);
NSArray *fontNames = [UIFont fontNamesForFamilyName:obj];
[fontNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
NSLog(#"--- %#",obj);
}];
}];
label.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:17];
I made a library to solve this problem:
https://github.com/Nirma/UIFontComplete
All fonts are represented as a system Font enum and the library also details a way of using it with your custom fonts in the read me.
Basically this:
let font = UIFont(name: "Arial-BoldItalicMT", size: 12.0)
Is replaced with either this:
let font = UIFont(font: .arialBoldItalicMT, size: 12.0)
Or this:
let myFont = Font.helvetica.of(size: 12.0)
This is how you get all font names in your project. That's it ... 3 lines of code
NSArray *fontFamilies = [UIFont familyNames];
for (int i=0; i<[fontFamilies count]; i++)
{
NSLog(#"Font: %# ...", [fontFamilies objectAtIndex:i]);
}

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 sizewithfont doesn't work?

I have the following code:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *currentMessage = [FeedMessages objectAtIndex:indexPath.row];
NSLog(currentMessage);
UIFont *font = [UIFont systemFontOfSize:14];
NSLog([NSString stringWithFormat:#"Height: %#",[currentMessage sizeWithFont:font forWidth:270 lineBreakMode:UILineBreakModeWordWrap].height]);
return [currentMessage sizeWithFont:font forWidth:270 lineBreakMode:UILineBreakModeWordWrap].height;
}
Can anybody tell me why "[currentMessage sizeWithFont:font forWidth:270 lineBreakMode:UILineBreakModeWordWrap].height" is always returning null or nil?
I've checked and currentMessage is populated correctly.
Any ideas?
Go through this question. It describes that - you must have to use, CGFLOAT_MAX or see following code ( grabbed from there . )
NSString *text = #"A really long string in here";
CGSize theSize = [text sizeWithFont:[UIFont boldSystemFontOfSize:18.0f] constrainedToSize:CGSizeMake(265.0f, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
NSString *stringHeight = [NSString stringWithFormat:#"%f", theSize.height];
You are not using NSLog() in correct format. it should be
NSLog(#" %#",[NSString stringWithFormat:#"Height: %f",[currentMessage sizeWithFont:font forWidth:270 lineBreakMode:UILineBreakModeWordWrap].height]);
and %f should be used for float.
Apart from your flawed type juggling which has been noted above, sizeWithFont:forWidth:lineBreakMode: only measures dimensions of the (truncated) first line, oddly enough.
you want to use sizeWithFont:constrainedToSize:lineBreakMode: which actually splits text over lines and takes the lines into account. Use a CGSizeMake(270.0f,999999.0f) to get the full height of the text.
see http://developer.apple.com/iphone/library/documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html
I spent 2 hours on this, freaking out. For me the problem was in such a small and stupid thing: I had a 'release' mode switched on. So, when going with debugger, it was stopping at the proper code lines (no idea why debugger should do that in release mode), but didn't show what I expected.