Table cell height by UITextView where content alignment is NSTextAlignmentJustified - ios

I have a UITextView where content is aligned by NSTextAlignmentJustified. In the cellForRowAtIndexPath: add this text view to cell content view and change frame according it's content by
UITextView *commentsTextView = (UITextView *)[self getCommentField:comment];
[cell.contentView addSubview:commentsTextView];
CGRect tempFrame = commentsTextView.frame;
tempFrame.size.height = commentsTextView.contentSize.height;
commentsTextView.frame = tempFrame;
So far, so good. Now, how to detect contentSize of that view for heightForRowAtIndexPath:?
I tried
NSString *comment = [[self.allComments objectAtIndex:indexPath.row] objectForKey:#"commentText"];
CGSize constraintSize = CGSizeMake(315.0f, MAXFLOAT);
CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14.0]
constrainedToSize:constraintSize
lineBreakMode:NSTextAlignmentJustified];
Also I tried lineBreakMode:NSLineBreakByWordWrapping and so. But cell height is always smaller when text is long, because there seems to be no way how to coumpute size of justified text (because of the white spaces in the middle of text). Font is same.

OK, i got it. UITextView has 8 pixels insect from each side, co my CGSizeMake(315.0f, MAXFLOAT); have to be CGSizeMake(299.0f, MAXFLOAT);

Related

How to get a height a UITextView should be given width and length of text?

I am adding a UIView that contains a UITextView which is constrained to the top, left, and bottom of the view.
The width of the UIView should be the screen size's width which in turn will be the UITextView's width.
When I go to create this UIView, I can make it's CGSize to the screen size's width, but I am not sure on how to calculate the height.
How can I figure out what height I must set this UIView so that the UITextView can properly show? Is there a way I can figure out the number of lines a UITextView would have given a certain width?
You can use the following code to Get a dynamic Rect:
NSString *myDynamicString = #"Hello World!";
CGSize textRect = [myDynamicString boundingRectWithSize:CGSizeMake(MAX_WIDTH, MAX_HEIGHT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont fontWithName:#"YouFontName" size:15]}
context:nil];
Note
MAX_WIDTH Width allowed to expand the rect. If you give 200 then the rect will exapand till 200 and then break and Vice Versa for MAX_HEIGHT
Use this code
CGSize constraintSize = CGSizeMake(textView.width - 2*textView.textContainer.lineFragmentPadding, CGFLOAT_MAX);
CGFloat messageTextViewHeight = [text boundingRectWithSize:constraintSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName: textView.font}
context:nil].size.height;
-(CGSize)getSizeForText:(NSString *)text maxWidth:(CGFloat)width font:(NSString *)fontName fontSize:(float)fontSize
{
CGSize constraintSize;
constraintSize.height = MAXFLOAT;
constraintSize.width = width;
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:fontName size:fontSize], NSFontAttributeName,
nil];
CGRect frame = [text boundingRectWithSize:constraintSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributesDictionary
context:nil];
CGSize stringSize = frame.size;
return stringSize;
}
First of all if you are using auto-layout this will be done out of the box, you don't have to do anything just setup constraints of auto-layout properly.
NSSString API is not very handy (as you can see in other answers) it is easy to miss something. I prfer use -(CGSize)sizeThatFits: from UIView.
UIView *textView = self.textView;
CGSize fitSize = { CGRectGetWidth(textView.frame), CGFLOAT_MAX };
CGSize fitSize = [textView sizeThatFits: fitSize];
NSLog(#"Your desired height: %f", fitSize.height);
It is more reliable and it should take into account all properties of text inside UITextView. I used this for UILabel didn't test for UITextView but it should work nicely.
If you want to see all the text in the text view an have the surrounding views around it adapt to contain it the easiest way would be to use a UILabel instead. Then you could just use constraints with priorities. Set the UILabel number of lines to 0 so that it automatically wraps. Then set the contentCompressionResistancePriority to 1000 for vertical axis. Then you don't need to worry about the sizes. Let autolayout do the work for you.

Why is so much extra space being added to my UILabel when I try to change height to fit text?

I have no idea why the height of my UILabel is expanding to such a great height. It leaves the text of my UILabel in the centre. I don't want all of this extra space...
Unwanted extra space
Here is my code (I set the text before this point):
self.infoDescription.numberOfLines = 0;
[self.infoDescription sizeToFit];
self.infoDescription.frame = CGRectMake(20, self.infoAdultSize.frame.size.height+self.infoAdultSize.frame.origin.y+10, self.infoView.frame.size.width-40, self.infoDescription.frame.size.height);
Please help :( I just want the height of the UILabel to fit the text exactly.
First set the frame and then make size to fit of label.
**self.infoDescription.frame = CGRectMake(20, self.infoAdultSize.frame.size.height+self.infoAdultSize.frame.origin.y+10, self.infoView.frame.size.width-40, self.infoDescription.frame.size.height);
[self.infoDescription sizeToFit];**
Try this:
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *myString = #"This is a long string which wraps";
UIFont *myFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize myStringSize = [myString sizeWithFont:myFont
constrainedToSize:maximumSize
lineBreakMode:self.myLabel.lineBreakMode];
(original source)
Please check this answer it works for me and it is exactly what you are looking for.
//Calculate the expected size based on the font and linebreak mode of your label
// FLT_MAX here simply means no constraint in height
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);
CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font constrainedToSize:maximumLabelSize lineBreakMode:yourLabel.lineBreakMode];
//adjust the label the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;

UIScrollView size to match UITextView size

I have a UIScrollView with a block of text in a UITextView. The text could be any amount of words coming from a server.
I want the scroll view to be the correct scroll size to match the size of the UITextView.
What is the current practice to do this?
Screenshot:
UITextView is an extension of UIScrollView. So you can get its content size using contentSize propery.
You can use something like below to get the height for your textview
CGSize size = [#"Your string"
sizeWithFont:[UIFont fontWithName:#"TimesNewRomanPS-BoldMT" size:22]
constrainedToSize:CGSizeMake(500, CGFLOAT_MAX)];
_textView.frame = CGRectMake(x,y, width, size.height);
_scrollview.frame = CGRectMake(x,y, width, size.height);
or there is a littl hack you can use :p
Use a Label to get the height for your text view.
UILabel *tempLabel = [[UILabel alloc]initWithFrmae:_textView.bounds];
tempLabel.numberOfLines = 0; // Important to do
tempLabel.text = #"Your Text";
[tempLabel sizeToFit]; // This will resize your Label and now you can use it's height to manage your textView.
Now use this tempLabel's height
tempLabel.frame.size.height

iOS: How can I achieve design with dynamic length text?

How can I make a simple design like in the image below where text length is dynamic? In the image below there are two sections Ingredients and Instructions with dynamic text length. There could be more sections.
Should I go for UIView with a UIScrollView or Table View? Any kind of help would be appreciated.
Try this approach.
1. Use UITextView this will give you possibility to scroll text inside UITextView if text will be very big.
2. Get the size of you text view
// return the size for UITextView for both IOS7 and IOS6
-(CGSize) getSizeWithMaxLabelSize:(CGSize) maxLabelSize forTextViewWithText:(NSString *) text
{
CGSize expectedLabelSize;
CGSize maximumLabelSize = maxLabelSize;
if (SYSTEM_VERSION_GREATER_THAN(#"6.2")) {
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[UIFont fontWithName:#"Arial" size:12] forKey: NSFontAttributeName];
CGRect rect =[text boundingRectWithSize:maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:stringAttributes context:nil];
expectedLabelSize = rect.size;
expectedLabelSize.height = ceilf(expectedLabelSize.height);
expectedLabelSize.width = ceilf(expectedLabelSize.width);
} else {
expectedLabelSize = [text sizeWithFont:[UIFont fontWithName:#"Arial" size:EPCommentViewFontSize] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];
}
return expectedLabelSize;
}
3. Use this method (2) when you calculate cell height for you table
- tableView:cellForRowAtIndexPath:
You should go for UITextView/UILabel with UIScrollView. UILabel is preferable if the content is not editable and you do not need the text scrolling on the fixed area.
If your needs fulfilled by these, you need to go with UILabel with UIScrollView.

Resize UITableViewCell to UILabel's height dynamically

I want to resize cell's height according to the label's height and label's height according to text. Or is there any way I can resize the cell's height according to the text entered in UITextView?
THIS METHOD IS DEPRECATED SINCE iOS 7.0.
There is a UITableView delegate method called heightForRowAtIndexPath that is called before you create a cell or a table.
You could use the NSIndexPath passed to it to get the text at a specific row and use the sizeWithFont method from UIStringDrawing.h to compute a CGSize for that row.
For example:
CGSize size = [text sizeWithFont:font
constrainedToSize:maximumLabelSize
lineBreakMode:UILineBreakModeWordWrap];
And finally you would return size.height.
--For iOS7--
Basing this off of Josh Vera's answer … place this in heightForRowAtIndexPath.
I have my table data stored in an NSArray *tableData.
// set the desired width of the textbox that will be holding the adjusted text, (for clarity only, set as property or ivar)
CGFloat widthOfMyTexbox = 250.0;
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get a reference to your string to base the cell size on.
NSString *cellText = [self.tableData objectAtIndex:indexPath.row];
//set the desired size of your textbox
CGSize constraint = CGSizeMake(widthOfMyTextBox, MAXFLOAT);
//set your text attribute dictionary
NSDictionary *attributes = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:14.0] forKey:NSFontAttributeName];
//get the size of the text box
CGRect textsize = [cellText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
//calculate your size
float textHeight = textsize.size.height +20;
//I have mine set for a minimum size
textHeight = (textHeight < 50.0) ? 50.0 : textHeight;
return textHeight;
}
I haven't tested it for iOS<7, but I believe it should work for that as well.

Resources