UITextView contentSize.height larger than necessary? - ios

UITextView scrolls even when all the text fits within its frame. It scrolls as if there are two new lines at the bottom of the text, but there aren't. So, its contentSize.height seems to be a couple lines larger than the text. How do I get rid of this? I.e., how do I tighten up the content size?

You can set up the contentSize for that UITextView so that it tightens to the text.
You can make use of NSString methods named sizeWithFont.... You can check full list here: http://developer.apple.com/library/ios/#documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html
I've noticed some issues working with some of them, but one that never fails me is:
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
I suppose you have a fixed width and want to find out the correct height. Considering a fixed 200px width, it would be something like:
NSString *myText = #"Some text...";
CGSize tightContentSize = [mytext sizeWithFont:[UIFont fontWithName:#"Helvetica" size:12] constrainedToSize:CGSizeMake(200, 10000000)].height;
[myTextView setContentSize:tightContentSize];
Take into consideration that your UITextView has an 8px padding in all directions, so if your UITextView frame is 200 width, you would actualy have a 184px width for text.

It's late but, for other people, try with:
self.textView.contentInset = UIEdgeInsetsZero;
That's work for me.

Related

Unable to show all content of UILabel

I have a UILabel which is by default showing only 3 lines of text. I want to display all text content in some cases. I have tried everything I found, but nothing works. Here is my latest try:
CGRect labelSize = [contents.contentLanguage.Description boundingRectWithSize:CGSizeMake(self.view.frame.size.width * 0.97, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil];
cell.descLbl.frame = CGRectMake(labelSize.origin.x,
labelSize.origin.y,
ceil(labelSize.size.width),
ceil(labelSize.size.height));
[cell.descLbl setNumberOfLines:0];
[cell.descLbl setLineBreakMode:NSLineBreakByWordWrapping];
[cell.descLbl sizeToFit];
Maybe you should look at maybe using the UITextView instead? It's much better suited for multiline text.
https://developer.apple.com/documentation/uikit/uitextview
Ok, so I was able to resolve this issue by changing the height of the UILabel from the .xib file to >=0
Please use UiTextView in place of UILabel
textviewobj.text=#"";
[textviewobj sizeToFit];
You have two ways (choices) to do it:
Use UITextView without editing permission
Use UILabel with numberOfLines = 0
Use UITextView without editing permission
If you've fixed space (limited area to display your content i.e. fixed height) to diplay your content and you can't work with scrollable content then you should use UITextView without editing permission.
Use UILabel with numberOfLines = 0
If you've flexible space (no limited space/area to display a your content i.e. fixed height) to display your content, then you should use UILabel with number of line = 0.
Do not assign height value (constraint) if you want a flexible UILabel with height, that fits according to size of your content.
Or Assign minimum height value (constraint like >= 30) if you want to have/set a minimum area for content, whether there is no content to be display.

UIlabel shows extra space before text

I have used UILabel in my app. It is working properly in portrait mode. But when I open my app in landscape mode it shows content in center of UIlabel. I have tried sizeToFit but it is not working. As soon as I increase uilabel's width spacing starts to arrive in uilabel.
My code:
self.contentLabel.text = labeltext;
[self.contentLabel setNumberOfLines:0];
[self.contentLabel sizeToFit];
I suspect your UILabel itself and not the text within it is actually aligning incorrectly upon rotation. Make sure the label stays aligned to the top of the view. Try:
self.contentLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight;
or
self.contentLabel.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
Edit: One other thought.
If auto layout's enabled and you're calling sizeToFit in viewDidLoad, perhaps the view is resizing after auto layout lays out the subviews. Try putting your code in viewDidLayoutSubviews instead.
If you add a UILabel with height bigger than the height of the text, it's normal if that happened and there is no way to change this alignement (Vertical center).
I have two solutions for this problem:
Work with constraint :
This constraint Greater than or equal is just magic.
If you create the label with the code I suggest to work with that:
UIFont *fontReceive = [UIFont systemFontOfSize:[UIFont systemFontSize]];
CGSize sizeText = [text sizeWithFont:fontReceive constrainedToSize:CGSizeMake(260, 9999) lineBreakMode:NSLineBreakByWordWrapping];
Hope that will help!
The best solution is to change the height of your cell according the the amount of text your are populating it with.
Please see this code below as an example.
NSString *content = **YOUR_STRING_LABEL_INTENDED_CONTENT**
CGSize maximumLabelSize = CGSizeMake(390, 1000); //For example - Put in your desired label width here and maximum size etc.
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:13] forKey: NSFontAttributeName]; //This allows a calculation to be made of the space taken up, so if you're using a custom or large font it will calculate accordingly.
CGSize newExpectedLabelSize = [content boundingRectWithSize:maximumLabelSize options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin attributes:stringAttributes context:nil].size;
Now you can change the height of your label by using this next line, where label is the name of the label you made.
GCRect frame = label.frame;
frame.size.height = newExpectedLabelSize.height;
label.frame = frame;
I hope this helps, cheers, Jim.

UITextView Word Wrapping Unexpected behavior

I have a UITextView with Content and frame size widths equal to 348, but word wrapping happens whenever text width on a line exceeds 338.61. Does anyone know why this might be happening? How can I access the width that the UITextView uses for word wrapping dynamically?
As of iOS 7, yes. It's a combination of textContainerInset and lineFragmentPadding.
UITextView *textView = ...;
CGFloat wrappingWidth = textView.bounds.size.width - (textView.textContainerInset.left + textView.textContainerInset.right + 2 * textView.textContainer.lineFragmentPadding);
Which is a nice value to know about. You can use it in boundingRectWithSize: calls, for example:
CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(wrappingWidth, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin // this is important
attributes:#{ NSFontAttributeName: textView.font } // and any other attributes of your text
context:nil];
Also cool is the fact that you can set textContainerInset and lineFragmentPadding, so if you want to increase this or have a UITextView that renders with no insets (so it matches a UILabel, for example), you can.
Nothing wrong with the answer above but I have been researching the UITextView word wrapping behavior and have discovered that although one can adjust the contentSize of the textview and the corresponding size of the textContainer, one additional method of changing the text wrap position (when using Auto Layout) is to make the trailing space to the SuperView into a negative value. This will allow one to push the word wrapping feature outward to the right. Not finished with the research just yet, but this tip should help anyone seeking to better control the UITextView word wrapping behavior.
Will post code once I'm complete but for now adjusting the trailing constraint of a UITextView will move the rightmost position of the word/character wrap.

UITextView text cut off when there is a large amount of text

I have a UITableViewCell subclass that contains a UITextView where scrolling is turned off. I set its frame like this, in my table view cell layoutSubviews method:
CGRect frame = self.bodyTextView.frame;
CGSize size = self.bodyTextView.contentSize;
frame.size = size;
self.bodyTextView.frame = frame;
This has been working fine for some time, but I've noticed that in a case where I have a particularly large amount of text, the text is getting cut off. I've set the text view frame background color to orange so I could verify that the frame was being set correctly. Here is an example (I am only showing the bottom portion of the text view):
The frame is the correct size based on the text (in this case 1019 points), but the text stops before the bottom of the text view. I have also seen the text get cut off part way through a line, (ie the text of the last visible line of text is cut off half way through horizontally). Does anyone have an idea what is happening here?
A few other points:
The text views work well for all my table view cells with shorter content.
If I increase the amount of text in the case shown above, the text view height increases, but the text still gets cut off at the same place.
According to this and similar answers, the problem could be that "the correct contentSize is only available after the UITextView has been added to the view ... Prior to that it is equal to frame.size"
I'd suggest you to calculate the height in a different way, like -sizeWithFont: or -sizeTofit
Use this to get the textSize
// find the text width; so that btn width can be calculate
CGSize textSize = [#"YOUR TEXT" sizeWithFont:[UIFont fontWithName:#"Arial" size:20.0]
constrainedToSize:CGSizeMake(320.0f, 99999.0f)
lineBreakMode:UILineBreakModeWordWrap];
and then set height using this as :
CGRect frame = self.bodyTextView.frame;
frame.size = textSize;
self.bodyTextView.frame = frame;
Hope it helps you.
I had the same issue and resolved it working on the textView padding (in swift5):
yourTextView.textContainerInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
Hope it can help :)

How to find out when UILabel wordwraps

I have created a couple of different UITableViewCells for my tableViewController, this is because I have different bits of data I want to display depending what comes back. Because of this each UITableViewCell is of a different height.
This is all fine, However one of my UILabels has to display a large NSString, so large that I have had to word wrap it onto a second line, The only issue here is that it messes up my UITableViewCell formatting.
My question is, is it possible to flag or capture some type of action when a UILabel receiving a NSString has to use wordrap because the size of the NSString is too long?
Or is there a way to calculate the physical length (not how many chars are in the string) of the NSString so I can decide hey I need to reformat my UITableViewCell..
Any help would be greatly appreciated.
The usual way is to use sizeWithFont:constrainedToSize:lineBreakMode: to get the size of a string. You use it like this:
CGSize stringSize = [theString sizeWithFont:[UIFont fontWithName:#"Helvetica Neue" size:12] constrainedToSize:CGSizeMake(320, 3000) lineBreakMode:NSLineBreakByWordWrapping ];
This is set for the full width of a table cell, but you would want to use the width of your label instead.
i dont know if i understand well but you have the height of your tableviewcell right? and you have a NSString maybe in a UITextView and this height of content of textview is higher then tableviewcell. Well, you should first calculate the content of UITextview, add into a list and when heightforRowAtindexPath was called, you should calculate new height (content textview) plus something... And to solve the max length you should count a limit for chars or limit for lines..
Some usefull code:
//resize height with content of UITextView
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;
//delegate textview to calculate limit for text.
- (void)textViewDidChange:(UITextView *)textView{
NSInteger restrictedLength=140;
NSString *temp=textView.text;
if([[textView text] length] > restrictedLength){
textView.text=[temp substringToIndex:[temp length]-1];
}
}
remember, you need to calculate the limit/size content from UITextview before heightforRowAtIndexPath called. When it called you already need to know your max height for cell.

Resources