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.
Related
I'm seriously lost on this one.
Here's the shot:
The price on Tea's Tea Matcha... is being cut off. I simply cannot figure out why.
I'm using boundingRectWithSize:...
When I log the height of the label's frame after calling layoutIfNeeded, it's the height that it should be for each respective frame: the same height as boundingRect.size.height.
Also, when I log the text of the label, the price is in the log so it's not that either.
It's just this and a few other labels out of hundreds that are having this issue and I do not know why.
This is my code for setting the height of the label:
CGRect boundingRect = [self.nameLabel.attributedText boundingRectWithSize:CGSizeMake(self.frame.size.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
self.nameLabelHeightConstraint.constant = ceil(boundingRect.size.height);
[self layoutIfNeeded];
One thing I've noticed - if instead of calculating the height with boundingRect and setting it manually I use sizeToFit on the label, it has this same problem but if I scroll past the row and back to it, it's fixed and the price appears underneath.
Anyone know wtf is going on here?
I found I was able to fix the issue by changing the default height constraint constant. I lowered it significantly (it was large enough that it was touching the bottom of the Cell.xib view. I made it spaced closer to the view above it by 1 pixel, lowered the default height constraint constant in IB and changed the type from equals to greater than or equal to. These things combined (I'm not sure which if not all did it) seem to have fixed the problem.
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.
As far as I know, laying out paragraphs can be done with:
a) UITextView
Resizing the textview to fit the content in didlayoutsubviews
Example here: Weird thing occurs when using sizetofit of a UITextView in IOS7
b) UILabel
Setting the Lines to 0, using sizetofit
Example here: Multiple lines of text in UILabel
However, I am unable to get either of these to work in IOS7 (having previously used them in ios6.x). There must be a definitive and clear way to just lay out a paragraph, its such a seemingly simple task.To be specific, this is just a paragraph of text that is:
non-editable
variable length
Works consistently whether using storyboards or code only
So please, what is the way to do this?
UITextView works fine on iOS 7. If you don't use Auto Layout, then calling sizeToFit on UITextView object should be enough. If you do use Auto Layout, then make a height constraint on UITextView object and set its constant in code in the following way:
CGSize sizeThatFits = [self.textView sizeThatFits:CGSizeMake(yourAvailableWidth, MAXFLOAT)];
self.textViewHeightConstraint.constant = ceilf(sizeThatFits.height);
I've seen some problems with UILabel recently, e.g. Lines missing from tall UILabel when embedding NSTextAttachment
With the UILabel, I was able to to get this working by:
setting the lines to 0
setting my line break mode to word wrap
ensuring that the height constraint is set to a "greater than or equal to"
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.
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.