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.
Related
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.
I am using UILabels with numberOfLines=0 and lineBreakMode = NSLineBreakByWordWrapping in a "dynamic" UITableViewCell . I utilize AutoLayout to attach the label to its container cell at the top, bottom, trailing and leading edges. In iOS7, the label's height updates dynamically with its content, however in iOS8 it truncates prematurely (usually at 1 line, but sometimes at 2). In iOS8, I have confirmed that the intrinsicContentSize of the label is dynamically updating as expected, but the label's frame is not following suit. Here is the difference seen between iOS7 and iOS8:
I have read of similar bugs in iOS8, but have been unable to implement a workaround. I have tried setting the label's text to #"" and back to #"Abraham Lincoln: Vampire Hunter" (as mentioned in this question), but that does not remedy the issue. Also notice that in iOS8, the cell size does increase according to the label's intrinsicContentSize, but for whatever reason, the height of the label itself does not. Any suggestions would be greatly appreciated. I would be glad to provide more information as well.
iOS 8
iOS 7
This is my walk around
subclass of UILabel, and override this function.
-(CGRect)textRectForBounds:(CGRect)bounds
limitedToNumberOfLines:(NSInteger)numberOfLines
{
CGRect rect = [super textRectForBounds:bounds
limitedToNumberOfLines:numberOfLines];
float height = rect.size.height;
int hightRound = (int)roundf(height);
rect.size.height = hightRound;
return rect;
}
While typing in a UITextView sometimes it scrolls down to current line(case a) but it doesn't the other times(case b).
There's another problem which is:
The same UITextView sometimes show all the text in it (case 1) but other times it doesn't show the last line of text(case 2).
Whenever case 1 happens case a follows.
and Whenever case 2 happens case b follows.
This is the hierarchy of the view:
Size(variable height-fixed width) of these UITextViews as well as UICollectionViewCells are calculated using sizeWithFont:constrainedToSize:lineBreakMode:
Limits of height are set from 43 to 120.
if height>43 then enableScrolling is set to YES, otherwise to NO(Logic X).
Scrolling is enabled when textViewBeginEditing and Logic X is applied when textViewEnded Editing.
There is no scrolling in case 2.
Please suggest cause and workarounds.
On iOS7, I think that you could leave the UITextView's scrollEnabled property set to YES in all cases. If it contains less text it will just not scroll. If you set the property while configuring the cell, you might get this kind of weird behavior, because UIKit is reusing those cells and probably the UITextView too.
For making the last line visible, I'm guessing you need to calculate the text view size more accurately. Try using the attributedText to set the text, with all the formatting you need. Then, in order to calculate the size, you can do it like this:
NSAttributedString *text = self.yourCellsTextView.attributedText;
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:text];
CGSize size = [calculationView sizeThatFits:CGSizeMake(self.yourCellsTextView.frame.size.width, FLT_MAX)];
CGFloat finalMessageHeight = size.height;
Hope this helps :).
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 :)
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.