Sizing a UITableViewCell based on its contained UITextView - ios

I'm working on an iOS app at the moment where I'm displaying lots of text in table view cells. The text in question is stored in an NSAttributedString can span an indefinite amount of lines and can have inline attachments such as images. The issue here is that I can't seem to get an accurate measure of a given cell's height to pass on to the table view. Is there a performant, simple way to calculate the height of an arbitrarily complex NSAttributedString contained in a UITextView?

You can call the boundingRectWithSize:options:context: method to find out its size.
[attributedString boundingRectWithSize:CGSizeMake(320.0f, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
You can substitute the 320.0f with whatever your expected width is for your text view.
Reference: NSAttributedString UIKit Additions Reference
As a footnote, NSString has similar categories outlined here.

I had many failed attempts at this until I came across the free Sensible TableView framework. The framework has what they call a TextViewCell that automatically resizes according to the text inside. Highly recommended.

Related

Getting wrong height for UITextView using boundingRectWithSize:options:context

I'm getting the wrong height for an UITextView even I'm calculating its size like this:
CGRect requiredHeight = [self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
context:nil];
When I add the height to my frame I can see all text but not the last line. I don't know why. (text was a HTML before I transformed it into a NSAttributedString).
so, the answer es very obvious but not always we see things like that so easily!.
EXPLANATION:
The answer is if we need to get the height for an specific field (it could be label, textView, etc) we should use a method from those fields to calculate its height, due to they could have some specific properties, if we calculate the height from a text (not considering the field) we are not considering those special properties the field could have.
SHORT ANSWER:
So short answer, for UITextView you should use [textView sizeThatFits:] to get its height, it's probably the best way to do it if you are not using auto layout.
advice:
I encourage you to use autolayout if you can easily migrate your UI.

Get Appropriate CGRect for an NSAttributedString

As it is clear from the title I'm trying to find the appropriate size for bounds of a UILabel containing an NSAttributedString which contains some images using NSTextAttachment.
Before using the attributedText property of the UILabel, I was using text property which carries the plain text only, and the method I was using was
sizeWithFont:font constrainedToSize:CGSizeMake(220, 9999) lineBreakMode:NSLineBreakByWordWrapping
And it was working fine. But now I have changed the type of contents in my UILabel and this method no longer gives the correct size ( Because it does not consider width of images ).
I have Googled a lot and the only thing I did end up with for NSAttributedString was
boundingRectWithSize:CGSizeMake(220.f, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
context:nil
But it is not returning the appropriate size and most of the content is lost in UI using this method. So please either suggest another solution or if you are suggesting boundingRectWithSize please come up with clear instruction on how can I make it work.
Just in case it helps, What I'm trying to show is a text message that may contain smilies (Custom Images, not Emojis of course) and those smilies are stored and shown as NSTextAttachments.

Changing UITextView height depending of it text

i have app that have table with many cells, when user tap on it, then detail view controller appear. Detail View Controller have an image and UITextView, that is not editable and it purpose only for showing text (just like label). Text it contain come from an xml file, sometimes it have several rows, sometimes there is a lot of text.
What i want is - to make UITextView height change depending of amount of text it have. For example, for several rows it might be 50 pixels height, in other case 300 pixels. How could i measure correct height and set it for UITextView? Again i want to point that it purpose only for showing text, not edit in any way. My second task is to measure final UITextView height and store it in some variable.
And there is what i've tried:
CGRect textViewRect = self.myTextView.frame;
textViewRect.size.height = self.myTextView.contentSize.height;
self.myTextView.frame = textViewRect;
But apparently its not working. Any idea how to achieve that?
Any advice would be appreciated, thanks!
Use this method of UIView:
- (CGSize)sizeThatFits:(CGSize)size
Typically you want your view limited in width, but any height. So you pass in a size with width as much as you want, and height for example 10000.0, so it gets as high as it needs. This returns how big the view needs to be according to its current content.
Try this
UITextView *textview1;
[textview1.text sizeWithFont:text.font constrainedToSize:textview1.frame.size];

Calculation Frame of a UILabel Subclass

The bottom line is that I'm trying to reproduce the UI that iMessage has.
For the Label:
The special padding of that type of text made me create a custom UILabel. Here's the code under drawTextInRect:
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, UIEdgeInsetsMake(0, 15.0, 5.0, 15.0))];
No mystery for now.
The problem comes when my cell (that contain that label has to calculate height).
The Label gets a rounding effect on the label like so:
cell.message.layer.cornerRadius = 18;
[cell.message sizeToFit];
Apparently I can't get the proper height and width of that label. I'm using sizeToFit and then I mesure the possible sizes with "sizeWithFont:" (deprecated in iOS 7) and "boundingRectWithSize:".
The only way the text can show properly is adding manually an undetermined amount of size to height and width once the calculations are made.
The best I can get then is a screen that may look good but still has some problems and not draws properly the texts.
The link has a screen of some of the screens not showing properly.
The only answer I've been able to see looking at code from other people is that they at some point make their own calculations based on letter size.
Anyone with this problem check : https://github.com/jessesquires/MessagesTableViewController
It was the only source I could find, at the end for some cases the boundingRectWithSize is not good enough.

Determine padding and size of iOS UITextView

Project
I am attempting to replicate the native iMessage app. I have used AcaniChat as a foundation.
I wanted automatic highlighting, so I modified the code to use UITextView instead of UILabel. I realize there are options such as FancyLabel and Three20. However, UITextView does this natively.
Problem
I am having a difficult time getting the padding/size of UITextView right. I updated the contentInset property based on suggestions in other answers.
msgText.contentInset = UIEdgeInsetsMake(-11.0f, -8.0f, 0.0f, -8.0f);
I am also determining the size with the following:
CGSize size = [[(Message *)object text] sizeWithFont:[UIFont systemFontOfSize:kMessageFontSize]
constrainedToSize:CGSizeMake(kMessageTextWidth, CGFLOAT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
Nonetheless, some text is still being cut off (see image below). Notably the phone number and email address (right) as well as the "that cut off?" (left)
I have verified this is not due to the dataDetectorsTypes property.
Question
I can solve this by increasing the CGRect of the UITextView. But I want to better understand the affects of margin/padding and size of the UITextView. I don't want to arbitrarily increase the size by 20.0f to make it work.
As such, what is the code or combination of code that I can reliably set the size of the message bubble?
Not a solution for your problems with UITextView but ...
I had similar problems and decided to give core text a chance. You have simply more control about what is happening.
You could have your string attributed using regex statements to make links/emails/phone numbers visible and have furthermore the chance to use even other fonts.

Resources