As I get strings of text down from my database, I need to know how big to make the UITextField and how big to make the Cell of the table that contains the UITextfield.
Are there any clever methods that can determine this? Since it will of course depend on the textfield width and the font used.
Thanks
-Code
NSString has a method sizeWithFont:contrainedToSize: that will give you to the size of a string with a particular font:
UIFont *font = [UIFont systemFontOfSize:12.f];
CGSize size = CGSizeMake(textView.frame.size.width, 1000.f);
CGSize stringSize = [myString sizeWithFont:font constrainedToSize:size];
Related
I am currently using
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
to get the size of an NSString. However, when that string includes emojis, it seems to calculate the size for the literal unicode character rather than taking into account the size of the emoji itself, rendering the returned size incorrect.
How do I correctly get the size of the string with emoji characters, as it will appear in a uilabel?
The NSString is not presenting the emoji, it's representing a string, so the sizeWithFont will only account for the string.
I would use:
CGRect labelFrame = label.frame;
labelFrame.size = [label sizeThatFits:CGSizeMake(100, 9999)];
[label setFrame:labelFrame];
or
//Alternatively
[label sizeToFit];
Bare in mind that sizeToFit calls the sizeThatFits: method, so in terms of just setting the label to the right height, sizeThatFits: is quicker, and much easier on the eye.
I struggled with this same thing for a while, attempting multiple solutions including the accepted answer, which did not work for me. I solved this by creating an NSAttributed String with the text, then using the NSAttributedString method boundingRectWithSize:options:context: to get the size of the string.
NSString *text = //some text
CGFloat maxSize = //text size constraints
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text
attributes:#{NSFontAttributeName : font
}];
CGRect boundingRect = [attributedString boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];
CGSize fitSize = boundingRect.size;
Minor quest - looking for a clean way to dynamically set the size of tables in a resonably generic way (snippets below are from http://pastebin.com/E2pUFRg4).
Now I thought something like
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *text = [items objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(self.view.bounds.size.width-24.f, CGFLOAT_MAX);
UITableViewCell * cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
CGSize size = [text sizeWithFont:cell.textLabel.font
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height + 12.f, tableView.rowHeight);
return height;
}
would nicely cut it. But unfortunately on the first call to tableView:heightForRowAtIndexPath: the size of the font on the textlabel is set to 0 (the font itself is otherwise setup). It only gets popoulated to something sensible after the first draw.
So I find myself having to change this to something like:
....
UIFont * font = cell.textLabel.font;
if (font.pointSize == 0)
font = [UIFont systemFontOfSize:20];
CGSize size = [text sizeWithFont:font
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
.....
which does the trick. But now we suddenly have a hardcoded font size assumption of 20. Which sort of sucks.
So my questions now are
Any way to prevent this ? I.e. hardcoding it this much ?
I also guesstimate the X and Y borders/inset at 2x6 vertical and 2x12 horizontal.
is there any way to learn this dynamically or from a constant (as to make it as close to the proper defaults on an iPhone and iPad-UIPopover view) ?
And finally:
Suggestions for a cleaner way to do this - which also allows for the detailLabel or similar extra fields to be taken into account.
Complete sample at http://pastebin.com/E2pUFRg4.
Thanks,
Dw.
I think you need to more or less "hardcode" your font size anyway. If you get it from interface builder, or from a central constants file - or even in code - it is always somehow hardcoded.
If you need to distinguish between device types (iPhone, iPad) etc. you can still use different values according to UI requirements.
I usually set up a central configuration file for values like this. There you could also "hardcode" your standard margin values, as well as the font sizes of other cell labels. It is common practice to calculate as many values dynamically as possible to reduce the number of constants, but to still resort to constants to "anchor" these values.
A subquestion is:
How do I determine what the built-in internal margins of a UITextview are?
I have a long master string of text that I am trying to split into separate UITextView pages that I can then scroll from page to page inside a UIScrollView. I use the following method to determine what the height of a string in a UITextView is and whether the string is over the height limit:
-(NSNumber *)getHeightByWidth: (NSString *) myString
mySize: (UIFont *) mySize
myWidth: (NSNumber *) myWidth
{
int intMyWidth = [myWidth intValue];
CGSize boundingSize = CGSizeMake(intMyWidth, CGFLOAT_MAX);
CGSize requiredSize = [myString sizeWithFont:mySize constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
NSNumber *retNumber = [[NSNumber alloc] initWithFloat:requiredSize.height];
return retNumber;
[retNumber release];
}
I call the getHeightByWidth method using the following cellFont as the input for mySize:
UIFont *cellFont = [UIFont fontWithName:#"Arial" size:14.0];
The UITextView is 320 pixels wide, but I notice that the text doesn't go from the left edge to the right edge as there are internal margins which look to be around 10 pixels on each side. So when I call getHeightByWidth I set myWidth = (320 - 10 - 10); But after building strings to fit within the UITextView, there are usually gaps on the last row that could be filled with the next words in the master string.
Can anyone tell me why these gaps on the last row of the text occur using this process for UITextView?
The built-in margins are represented by the property contentInset.
Also you can configure the margins yourself.
If you have your text view in IB, look for Content insets. The values must be 0, but it still displays some margin. Trying setting them to negative values such as -4 or -8.
In the code, do something like-
myTextView.contentInset = UIEdgeInsetsMake(-4,-8,0,0);
You have to set these values according to what you find suitable.
In my app I am assigning fixed width and height to uilabel and assigning some text to it. My problem is if the text length is more than the label height I want to show "..." at the end of the text eg "apple... " . Is there is any property to show like this?
Yes, please check the line break property and set it to truncateTail
label.lineBrakMode = UILineBreakModeTailTruncation;
Hope this helps,
CGSize maximumSize = CGSizeMake(300, 40); //to keep height fixed to 40 //or use (150,300) to keep width fixed to 150 and varying height .
NSString *myString =#"Text for lable";
UIFont *myFont = [UIFont fontWithName:#"marker felt" size:14];// font used for label
CGSize myStringSize = [myString sizeWithFont:myFont
constrainedToSize:maximumSize
lineBreakMode:label.lineBreakMode];
use MySTringSize to set the frame for label. And use nemberOfLines property for label, it might be helpfull.
I have a fixed size UITextView say width and height of 150,150.
The purpose is to display the thought of the day. Please note the size need to remain constant and I cant change it.
Now The length of the thought string varies with respect to thought. What I want to do is change the size of font of the text to make sure it dont show any empty space in UITextView if length is small or it dont show the scroll if its bigger.
So how to vary the font of UITextView according to the length of thought string.
What is wrong with the following code:
CGSize size;
BOOL run=TRUE;
CGSize txtViewSize = self.txt_tipView.frame.size;
while(run){
size = [self.txt_tipView.text sizeWithFont:[UIFont systemFontOfSize: currentSize] constrainedToSize:txtViewSize lineBreakMode:UILineBreakModeWordWrap];
if((size.width<=txtViewSize.width) && (size.height<=txtViewSize.height))
run = FALSE;
else
currentSize--;
}
self.txt_tipView.font = [UIFont fontWithName:#"Helvetica" size:currentSize];//[UIFont boldSystemFontOfSize:12];
What happens is the size of the text in TextView is always 60. That is each line has only one word.
Set an implicit font size, let's say the largest acceptable font you could use. Then, make a measurement of your text size with:
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize: currentSize] constrainedToSize: maxTextSize lineBreakMode:UILineBreakModeWordWrap];
If the size you obtain is off the acceptable bounds, adjust the font size and repeat. The maxTextSize should be the size of your UITextView.