Iphone sizewithfont doesn't work? - iphone

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.

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.

Autofit label, CGSize gives value zero

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];

Custom UITableView Dynamic Cell Height

I have search and searched through endless blogs and articles on how to determine a dynamic height for a custom UITableViewCell and its detailed text. I have really had a hard time finding any good documentation on this.
What I need to do is have the cell grow according to the the text inside but never go below a height of 70.
I have tried several of the answers for this type of question here on StackOverflow but none of them worked. My whole app is just about finished but I really need to get this accomplished before I release and its troublesome.
Here is what I am trying but I just get a slop of cells overlapping each other. From what I read I need to find the frame if the custom cell or textview in the cell as well but I am not sure how to do that or mix them all together to return one height.
Any Help would be greatly appreciated Thank you!
- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath
*) indexPath
{
CGSize aSize;
aSize = [[(Tweet*)[tweets objectAtIndex:indexPath.row]tweet] sizeWithFont:[UIFont
systemFontOfSize:14]
constrainedToSize:CGSizeMake(300.0, 1000.0)
lineBreakMode:UILineBreakModeTailTruncation];
return aSize.height;
}
I had a similar issue a while back and this helped me tremendously.
#define PADDING 10.0f
- (CGFloat)tableView:(UITableView *)t heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *text = [self.items objectAtIndex:indexPath.row];
CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(self.tableView.frame.size.width - PADDING * 3, 1000.0f)];
return textSize.height + PADDING * 3;
}
Hey there so you are going to need to store the list of strings in an NSArray and then you are going to need to calculate the height of the nsstring using sizeWithFont:constrainedToSize: the documentation is found here http://developer.apple.com/library/ios/#documentation/UIKit/Reference/NSString_UIKit_Additions/Reference/Reference.html
so your tableView method should look something like
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[UIFont fontWithName:"Helvetica" size:9] forKey: NSFontAttributeName];
CGSize cell_size = [string boundingRectWithSize:CGSizeMake(300,999)
options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin
attributes:stringAttributes context:nil].size;
if (cell_size.height > 70)
{
return cell_size.height;
}
else
{
return 70;
}
}
EDIT : THIS has been updated for iOS 7
I tried many solutions, but the one that worked was this, suggested by a friend:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
int height = [StringUtils findHeightForText:yourLabel havingWidth:yourWidth andFont:[UIFont systemFontOfSize:17.0f]];
height += [StringUtils findHeightForText:yourOtherLabel havingWidth:yourWidth andFont:[UIFont systemFontOfSize:14.0f]];
return height + CELL_SIZE_WITHOUT_LABELS; //important to know the size of your custom cell without the height of the variable labels
}
The StringUtils.h class:
#import <Foundation/Foundation.h>
#interface StringUtils : NSObject
+ (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font;
#end
StringUtils.m class:
#import "StringUtils.h"
#implementation StringUtils
+ (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
CGFloat result = font.pointSize+4;
if (text) {
CGSize size;
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil];
size = CGSizeMake(frame.size.width, frame.size.height+1);
result = MAX(size.height, result); //At least one row
}
return result;
}
#end
It worked perfectly for me. I had a Custom Cell with 3 images with fixed sizes, 2 labels with fixed sizes and 2 variable labels. Worked like a charm. Hope it works for you too.
Best regards, Alexandre.
iOS 7
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
NSString *text = #"Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello HelloHello HelloHello HelloHello HelloHello HelloHello Hello";
CGRect rect = [text boundingRectWithSize:CGSizeMake(280.0f, CGFLOAT_MAX) options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin attributes:#{
NSFontAttributeName: [UIFont fontWithName:#"Hellvetica" size:14.0f]
} context:nil];
return CGSizeMake(320.0f, ceil(rect.size.height) + 10.0f);
}
I just wrote about this problem and how I finally decided to solve it. You can read about it here: Dynamic UITableView Cell Height Based on Contents
Basically, I created a UITableView subclass that automates the handling and calculation of dynamic cell height for both default and custom cells. It is not a silver bullet and probably needs to be extended and tweaked, but I have used it as is in several apps with good result.
You can grab the code here: https://github.com/danielsaidi/AutoSizeTableView
Hope it helps!
(...and if it didn't, I'd love to hear why not)
Use UITableViewDelegate method:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// here you need to get height of your textlabel in your custom cell.
MyCustomCell *myCell = (MyCustomCell *)[tableView cellForRowAtIndexPath:indexPath];
return myCell.myTextLabel.frame.size.height + 20;
}
Something like this

Line breaks not working in UILabel

I'm loading some help text from a plist and displaying the same in the form of UILabels housed in a UIScrollView. Portion of the code follows:
UILabel *sectionDetailLabel = [[[UILabel alloc] initWithFrame:CGRectMake(34, myOriginForThisSection, 286, 20)] autorelease];
sectionDetailLabel.backgroundColor = [UIColor clearColor];
sectionDetailLabel.numberOfLines = 0;
sectionDetailLabel.font = [UIFont systemFontOfSize:12];
sectionDetailLabel.textColor = [UIColor blackColor];
sectionDetailLabel.textAlignment = UITextAlignmentLeft;
sectionDetailLabel.lineBreakMode = UILineBreakModeWordWrap;
[baseScrollView addSubview:sectionDetailLabel];
[sectionDetailLabel setText:myStringForThisSection];
[sectionDetailLabel sizeToFit];
While any 'long' text is getting wrapped into multiple lines correctly, I'm unable to manually insert any line-breaks using newline '\n' characters in 'myStringForThisSection'. I only see the characters '\' and 'n' printed in the UILabel wherever I wanted the line-break, instead.
I looked this up and the general consensus seemed to be that setting numberOfLines to 0, setting the lineBreakMode to a valid value and invoking sizeToFit (or setting the frame of the UILabel based on sizeWithFont:) should do. All of which I seem to be doing in the code above - and works perfectly when fitting long strings of unknown length into multiple lines on the UILabel. So what could be missing here?
Note: All the variables used - baseScrollView, myStringForThisSection and myOriginForThisSection - were loaded before the above code began executing, and work fine.
UILabel doesn't interpret the escape sequence \n. You can insert the real character that represents the Carriage Return and/or the Line Feed. Make a char to hold your newline and then insert it.
unichar newLine = '\n';
NSString *singleCR = [NSString stringWithCharacters:&newLine length:1];
[myStringForThisSection insertString:singleCR atIndex:somePlaceIWantACR];
As long as your myStringForThisSection is mutable, that should do it.
I had trouble with Scot Gustafson's answer above in XCode 4.3
Try this instead:
unichar chr[1] = {'\n'};
NSString *cR = [NSString stringWithCharacters:(const unichar *)chr length:1];
Then use in your code something like this:
self.myLabel.text = [NSString stringWithFormat:#"First Label Line%#Second Label Line", cR];
I couldn't get Scott & DoctorG's solution to work (though I didn't spend too much time trying), but here's the simple solution that works for me when I'm extracting escaped text from an xml file.
Inside my string function class, I define:
+(NSString)escapeXml:(NSString*)string {
return [string stringByReplacingOccurrencesOfString:#"\\n" withString:#"\n"];
}

NSString drawAtPoint/drawInRect: Append "..." to truncated string

I am drawing a NSString using drawAtPoint (drawInRect, that makes no big difference).
There is a parameter to set the line break mode, but has anyone an idea how to append "..." to strings if they are truncated?
One option is, to check whether the string is short enough. If that is not the case, iteratively remove the last character until the string length + 3 euqals the maximum length.
I am sure there is a better solution. Anyone an idea?
Best,
heinrich
You'd better to use another NSString method:
- (CGSize)drawAtPoint:(CGPoint)point
forWidth:(CGFloat)width
withFont:(UIFont *)font
lineBreakMode:(UILineBreakMode)lineBreakMode
And specify UILineBreakModeTailTruncation as lineBreakMode.
Updating answer since drawAtPoint:forWidth:withFont:lineBreakMode: has been deprecated since iOS 7.0. Instead, you can now use drawInRect:withAttributes:
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
NSDictionary *textAttributes = #{NSFontAttributeName : [UIFont systemFontOfSize:20.0f],
NSParagraphStyleAttributeName : paragraphStyle};
[text drawInRect:textRect withAttributes:textAttributes];
You can use the NSStringDrawingTruncatesLastVisibleLine option with the NSStringDrawingUsesLineFragmentOrigin value.
[_text drawWithRect:_textRect options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine attributes:attributes context:nil];