I'm looking for 5 hours right now, and no solutions on whole stack overflow is working.
So I hope someone comes with the magic trick.
I set text to the textview like this :
[TextMessages setText:[fromOtherView objectForKey:#"message"]];
But the content does not fit the textview.
How can I make the UITextView big enough to fit the content?
I tried many options like :
CGRect frame = _textView.frame;
frame.size.height = _textView.textContainer.size.height;
_textView.frame = frame;
Its on iOS 7
Try following code: This works in iOS6 and iOS7
CGSize textViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)];
self.myTextView.height = textViewSize.height;
Check this link for more
Related
Using information I've gathered from multiple answers I found here on stackoverflow, I've been able to correctly size a UITextView's height using:
[bookQuoteTxtView sizeToFit];
[bookQuoteTxtView layoutIfNeeded];
I'm doing this because the UITextView will obviously contain different amounts of text as a result of what the user may have selected on a previous screen.
However, I'm still running into one strange problem.
It seems that when the text that gets passed into the UITextView contains a line-break, it throws the whole height thing off.
Here's the text without any line-breaks:
And here's the same text with a couple of line-breaks thrown in the middle:
As you can see (with the help of the orange & yellow background colors I added to the UITextView & ScrollView that contains it), the UITextView's height didn't resize appropriately and now the text gets cut off - all because of those linebreaks.
The code I'm using to do all this dynamic height-changing on the UITextView is:
// BookQuote TextView:
bookQuoteTxtView = [[UITextView alloc] initWithFrame:CGRectMake(5, 30, 310, 80)];
bookQuoteTxtView.backgroundColor = [UIColor orangeColor];
bookQuoteTxtView.font = [UIFont fontWithName:#"Arial" size:15];
bookQuoteTxtView.text = [NSString stringWithFormat:#"%#", bookObject.bookQuote];
[bookQuoteTxtView sizeToFit];
[bookQuoteTxtView layoutIfNeeded];
bookQuoteTxtView.editable = NO;
[scroller addSubview:bookQuoteTxtView];
// Now get the HEIGHT of the Book-Quote TextView:
CGRect textViewFrame = bookQuoteTxtView.frame;
CGFloat textViewFrameHeight = bookQuoteTxtView.contentSize.height;
textViewFrame.size.height = textViewFrameHeight;
bookQuoteTxtView.frame = textViewFrame;
So again, this works almost flawlessly for just about every string that gets passed into my UITextView box. Thus, different strings of different lengths all work, the UITextView's height adjusts automatically and everything's cool. Its just the line-breaks that throw everything off.
HAVING SAID THAT...
Its seems that line-breaks generated using "\n" in the string DO work, but line breaks that are embedded/encoded in a string that's coming in and being read from an Sqlite3 database - do NOT.
So you gotta wonder if that's where the problem lies.
Here's the code I use to read my date from the Database:
// Book Quote:
char *bookQuoteChar = (char *)sqlite3_column_text(statement, 4);
NSString *bookQuoteString;
if (bookQuoteChar == NULL) {
bookQuoteString = #"N/A";
}
else {
bookQuoteString = [[NSString alloc] initWithUTF8String:bookQuoteChar];
}
I'm thinking more and more that its the database that's causing the problem, but I'm presenting the entire picture here in its totality to make sure I'm still doing the height-readjustment stuff correctly.
Please let me know if something's jumping out at you or if there are any suggestions for fixes.
I can't really suggest much besides using a technique to set the contentSize of the UITextView.
textView.text = #"text from DB";
CGRect rect = textView.frame;
rect.size.height = textView.contentSize.height;
textView.frame = rect;
and then use any techniques that may be needed to additionally update the frame. Hope you solve the problem!
I'm fairly new to programming, and I have looked for an answer for a very long time. There are some posts about it, but nothing has solved my problem. I have a UIScrollView view that I get from the nib, everything is ok with this, the content length is good and scrolling works, but it just scrolls on the left side, if I try to scroll on the right side it doesn't scroll..
Here is the code,
- (void)viewDidLoad {
[super viewDidLoad];
NSString *descriptionString = _currentBook.description;
CGSize stringSize = [descriptionString sizeWithFont:[UIFont boldSystemFontOfSize:16] constrainedToSize:CGSizeMake(387, 9999) lineBreakMode:UILineBreakModeWordWrap];
_authorLabel.text = _currentBook.author;
_titleLabel.text = _currentBook.title;
_descriptionLabel.text = [NSString stringWithFormat:#"Description: %#",_currentBook.description];
[(UIScrollView *)self.view setContentSize:CGSizeMake(387, stringSize.height +50)];
}
Thanks in advance!
Its hard to understand the problem since we cant see your nib file, but its better practice to put the scrollView on top the view of the view controller, and connect it to an IBOutlet in your view controller.
In order to find the problem I would get rid of the textfields for testing purposes (I think the constrained 9999 might be a problem but I am not sure) and then print and post the frame of the scrollView and the Content size in runtime.I am betting that you will see some issue with the frame of the uiscrollview.
Thanks,
Ok, after copy-pasting and running some tests, I found out the problem.
The problem is in the wording of the question, your problem is not that the "scroll doesn't work on the right side" (As in: you move your finger up and down on the right side of the screen without triggering a scroll), the problem is that the contents, the label itself is going out of bounds, outside of the visible area of the scrollView, and the right-handed side is not visible.
First of all, you should note that the iphone resolution is 320x480 (640x960 for Retina), so you actually have to work with a smaller width (using 387 width will make it go out of bounds).
Second, take in account the x position of the label itself is also affecting the amount of visible text. With this in mind, a more generic code would be:
- (void)viewDidLoad
{
[super viewDidLoad];
// This number represents the total width of the label that will fit centered in
// the scrollView area.
CGFloat visibleWidth = self.view.frame.width - descriptionLabel.frame.origin.x*2;
// Use the number above to get a more accurate size for the string.
NSString *descriptionString = _currentBook.description;
CGSize stringSize = [descriptionString sizeWithFont:[UIFont boldSystemFontOfSize:16] constrainedToSize:CGSizeMake(visibleWidth, 9999) lineBreakMode:UILineBreakModeWordWrap];
// Fill data (why so many underscores?)
_authorLabel.text = _currentBook.author;
_titleLabel.text = _currentBook.title;
_descriptionLabel.text = [NSString stringWithFormat:#"Description: %#", _currentBook.description];
// Also, why didn't you resize the description label? I'm assuming that you forgot this.
// (Make sure that the descriptionLabel number of lines is 0)
CGRect frame = descriptionLabel.frame;
descriptionLabel.frame.size = stringSize;
// Now set the content size, since you're using the scrollView as the main view of the viewController,
// I'll asume that it's using the whole screen, so I'm gonna use the whole width
// of the screen (that's what UIScreen is for).
[(UIScrollView *)self.view setContentSize:CGSizeMake([UIScreen mainScreen].bounds.size.width, stringSize.height +50)];
}
Finally i've found my problem, I've added a uiview programmatically as a subview to some view and then to this View i've added my scroll view as a subview.. And then it would only scroll in the area of my UIView. It was nonsense to do it like this, still a lack of knowledge..
Thank you all for trying to help!
By default, the UITextView's contentView becomes scrollable when there is too much text to fit into the textview based on it's height.
I'd like to disable this and instead, update the height of the UITextView to fit in the text. The reason I'm doing this is because I'm adding the UITextView as a subview of a UIScrollView which should handle the scrolling, much like in the native Mail app (when you enter text, the whole view scrolls up, not just the textview.
Anyone got some ideas / has run into the same problem before?
It is very simply done like this:
CGRect frame = textView.frame;
frame.size = textView.contentSize;
textView.frame = frame;
This should set the height of the textview to appropriately fit all of its content.
Few little changes:
-(void)textViewDidChange:(UITextView *)textView {
CGFloat fontHeight = (textView.font.ascender - textView.font.descender) + 1;
CGRect newTextFrame = textView.frame;
newTextFrame.size = textView.contentSize;
newTextFrame.size.height = newTextFrame.size.height + fontHeight;
textView.frame = newTextFrame;
}
Adding the font height gives room for the autocorrection box when you spell something incorrectly.
The UITextView should also be set to not scroll:
[aTextView setScrollEnabled:NO];
Is there a way to get the correct size of an NSString using:
- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode
that doesnt get thrown off by 2 or 3 hundred character strings. At the moment if I try to use this method on these long strings it incorrectly calculates them and I end up with lots of whitespace at the bottom of the UITextView.
I've tried using UILineBreakModeWordWrap and UILineBreakModeCharacterWrap.
the resizing is being done in
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat result = 44.0f;
NSString* text = nil;
CGFloat width = 0;
CGFloat tableViewWidth;
CGRect bounds = [UIScreen mainScreen].bounds;
tableViewWidth = bounds.size.width;
width = tableViewWidth - 150;
text = stringWithLongWords;
if (text) {
CGSize textSize = { width, 20000.0f };
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:10.0f] constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];
size.height += 50.0f;
result = MAX(size.height, 44.0f+30.0f);
}
return result;
}
UITextView is not exactly like a UILabel wrapped in a UIScrollView. It has line spacing different from the font size and margins that sizeWithFont:constrainedToSize:linkBreakMode: doesn't account for.
Knowing your font size you might be able to calculate the # of lines and take line spacing into account. You can guess at the margins and try to trick sizeWithFont: to give a more useful answer.
The popular solutions seem to be:
just use a UILabel if you don't need any UITextView functionality
if you need hyperlinks, overlay UIButtons that look like hyperlinks over a UILabel
use an off-screen UITextView and its sizeToFit method to get a real answer
I had no luck w/ the 3rd option but it sounds like it should work, so perhaps I did something wrong.
I'm going to try using a UILabel and overlaying buttons for hyperlinks. We'll see how that turns out.
If that fails, there is always the option taken by Loren Brichter (of Tweetie fame): draw everything into a UIView yourself using CoreGraphics.
Good luck!
Check out this post How do I size a UITextView to its content?
It looks like textView.contentSize.height should work (with the caveat that the the correct contentSize is only available after the UITextView has been added to the view with addSubview)
You said that you have a UITableView with differing heights. Have you set the reuse identifier to the same thing for all of the cells? It could be that older cells with their height already set are being reused. If this is the problem, you should resize the cell again when it's being reused.
The best solution I have found so far is to have a separate hidden UITextView with the same font settings, and set its text. After that its contetSize should be accurate.
The width you are using is the width for your UITextView... but you aren't concerned with that width, you are concerned with the width of the actual text area nested inside the text view.
UITextViews, by default, have padding around their borders to produce a space in-between the typed text and the edge of the UITextView a few pixels wide (and long for the top)... To get the correct size you shouldn't use
textView.frame.size.width
but rather,
textView.frame.size.width-(textView.contentInset.left+textView.contentInset.right+textView.textContainerInset.left+textView.textContainerInset.right+textView.textContainer.lineFragmentPadding/*left*/+textView.textContainer.lineFragmentPadding/*right*/)
^Which takes the width of the UITextView and subtracts out all the padding so you are left with the width of just the type-able text area.
Same goes for height except for lineFragmentPadding doesn't have a bottom so you only subtract it out once instead of twice.
The final code is something like this:
CGSize textViewContentSize = CGSizeMake(theTextView.frame.size.width-(theTextView.contentInset.left+theTextView.contentInset.right+theTextView.textContainerInset.left+theTextView.textContainerInset.right+theTextView.textContainer.lineFragmentPadding/*left*/+theTextView.textContainer.lineFragmentPadding/*right*/), theTextView.frame.size.height-(theTextView.contentInset.top+theTextView.contentInset.bottom+theTextView.textContainerInset.top+theTextView.textContainerInset.bottom+theTextView.textContainer.lineFragmentPadding/*top*//*+theTextView.textContainer.lineFragmentPadding*//*there is no bottom padding*/));
CGSize calculatedSize = [theTextView.text sizeWithFont:theTextView.font
constrainedToSize:textViewContentSize
lineBreakMode:NSLineBreakByWordWrapping];
CGSize adjustedSize = CGSizeMake(ceilf(calculatedSize.width), ceilf(calculatedSize.height));
Inspired by #MrNickBarker's answer, here's my solution:
CGFloat width = 280.0f;
UITextView *t = [[UITextView alloc] init];
[t setFont:[UIFont systemFontOfSize:17]];
[label setText:#"some short or long text, works both"];
CGRect frame = CGRectMake(0, 0, width, 0);
[t setFrame:frame];
// Here's the trick: after applying the 0-frame, the content size is calculated and can be used in a second invocation
frame = CGRectMake(0, 0, width, t.contentSize.height);
[t setFrame:frame];
The only issue remaining for me is that this doesn't work with modified insets.
Still can't believe such twists are required, but since -[NSString sizeWithFont:forWidth:lineBreakMode:] does not respect insets, paddings, margins, line spacings and the like, it seems this is the only working solution at the moment (i.e. iOS 6).
I already did several searches on Stack Overflow and Google, but I couldn't find a solution to my problem.
I have a Detail View for a product that includes a UIScrollView and a few subviews (UIImageView, UILabel, UITextView). You can find an example here.
First I wanna autoresize the UITextView (not the text itself!) to the corresponding height. Then I wanna autoresize the entire UIScrollView so that it fits the height of my UITextView and the elements above it. I've tried the following code:
myUITextView.frame = CGRectMake(2.0, 98.0, 316.0, self.view.bounds.size.height);
[scrollView setContentOffset:CGPointMake(0.0, 0.0) animated:NO];
scrollView.contentSize = CGSizeMake(320.0, 98.0 + [myUITextView frame].size.height);
[self.view addSubview:scrollView];
98.0 + [myUITextView frame].size.height) because my thought was: After getting the height of myUITextView, add the height of the other subviews (98.0) to it.
Unfortunately it doesn't work very well. Depending on the content of the UIScrollView, it is too short or too long. I did some logging with the result that the height of the UITextView is always the same:
2010-01-27 14:15:45.096 myApp[1362:207] [myUITextView frame].size.height: 367.000000
Thanks!
There is actually a very easy way to do resize the UITextView to its correct height using its contentSize.
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;
One thing to note is that the correct contentSize is only available after the UITextView has been added to the view with addSubview. Prior to that it is equal to frame.size
A UITextView won't automatically resize itself to it's contents (not as far as I know anyway) so you need to get the size of the text yourself and size the UIView accordingly.
The functions on this page will help - you can use them to get the width and height of a string, something like
// Get the size that the string will render at
NSString *contents = #"This is the content of your UITextView";
CGSize areaSize = [contents sizeWithFont:myView.font forWidth:myView.frame.size.width lineBreakMode:UILineBreakModeWordWrap];
// Then set the frame of your UITextView to be the right size
myView.bounds = CGRectMake(0, 0, areaSize.width, areaSize.height);
Then, you can layout the other components around it.
Hope this helps,
S
PS Warning, the link to the docs is correct but my code example is untested, sorry :)