How to make a UITableViewCell with a UITextView inside that dynamically adjusts its height based on a UITextView?

I would like to have a tablew view with behavior similar to Apple's iPhone Contacts application: uitableviewcell with uitextview inside, so when I write in uitextview, uitextview increases its height, and therefore, accordingly, uitableviewcell dynamically adjusts its height. I scanned the entire network, finding only partial solutions and the lack of sample code!

Please help me I'm in despair

Tony

+42
iphone uitableview uitextview
Nov 21 '10 at 16:00
source share
10 answers

Looking at this, you have to be somewhat complicated. You need to calculate the height of the textView dynamically and based on the height of the TextView, you need to return the height for the cell.

It is very easy and somewhat tricky.

This is the code by which you can calculate the row size ....

First get the row size

NSString *label = @"Sample String to get the Size for the textView Will definitely work "; CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap]; over here .... NSLog(@"%f",stringSize.height); 

Secondly, dynamically create a textView in the cell. pass stringSize.height

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; //} NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section]; NSString *string = [d valueForKey:@"Description"]; CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap]; UITextView *textV=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, stringSize.height+10)]; textV.font = [UIFont systemFontOfSize:15.0]; textV.text=string; textV.textColor=[UIColor blackColor]; textV.editable=NO; [cell.contentView addSubview:textV]; [textV release]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section]; NSString *label = [d valueForKey:@"Description"]; CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap]; return stringSize.height+25; } 

After my fingers have suffered so much, I think this is enough code ... & will certainly help solve your problem.

Luck

+37
Nov 22 '10 at 6:37
source share

Create a custom UITableViewCell and add a UITextView to the cellView content element.

In LayoutSubviews, set textView.frame to the cell contentView.bounds (or do another custom layout).

When the contents of a textView changes (opens through a UITextViewDelegate), do two things:

1) call [tableView beginUpdates]; [tableView endUpdates]; [tableView beginUpdates]; [tableView endUpdates]; This will force the table view to recalculate the height for all cells (will call tableView:heightForRowAtIndexPath: . If your cell is a delegate for textView, you need to figure out how to get a pointer to a tableView, but there are several ways to achieve this. Or you can make the delegate your view controller ...

2) when tableView:heightForRowAtIndexPath: is called for this cell, return textView.contentSize.height . You can get your cell from here by calling [tableView cellForRowAtIndexPath]; Or, if you have only one of these cells, then cache the pointer to it in your viewController.

+12
Nov 25 '10 at 20:23
source share

The only problem I came across with the accepted answer was that we distribute a UITextView every time. I found that this caused problems with entering the view and updating the text immediately, as well as saving the view as the first responder. When I tried to reload a cell with a new height, it would try to add a new text element.

Because of this, I found a slightly different method to achieve the same goal. Hope this other solution can help people trying to implement the above code.

1) In the header file, specify a variable for the height of the text and textView:

 UITextView * _textView; NSInteger _textHeight; 

Setting a variable means that we can load the view as a specific height if we load text into a textView and also reduce complexity.

2) Download the text view and add it to our cell

 _textView = [[UITextView alloc] init]; _textView.delegate = self; _textView.returnKeyType = UIReturnKeyDone; _textView.font = [UIFont fontWithName:@"Helvetica" size:16]; if (![_user metaStringForKey:bBioKey].length) { _textView.text = @"Placeholder text"; _textView.textColor = [UIColor lightGrayColor]; } - (UITableViewCell *)tableView:(UITableView *)tableView_ cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath == 0) { // Add logic to choose the correct cell if (_textView.superview != cell) { [cell addSubview:_textView]; _textView.keepTopInset.equal = KeepRequired(7); _textView.keepBottomInset.equal = KeepRequired(7); _textView.keepRightInset.equal = KeepRequired(10); _textView.keepLeftInset.equal = KeepRequired(70); } } } } 

Using keeplayout allowed us to keep our text field always at the same height as the cell. We also add only UITextView once.

3) Add code to calculate text height

 - (NSInteger)getHeightOfBio: (NSString *)text { UILabel * gettingSizeLabel = [[UILabel alloc] init]; gettingSizeLabel.font = [UIFont fontWithName:@"Helvetica" size:16]; gettingSizeLabel.text = text; gettingSizeLabel.numberOfLines = 0; CGSize maximumLabelSize = CGSizeMake(240, 9999); // this width will be as per your requirement CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize]; return expectedSize.height; } 

I tried a lot and found that it works better

4) Add some logic to the cell height to use this:

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) { // Set the height for our changing textView return 30 + [self getHeightOfBio:_textView.text]; } return 44; } 

Obviously, we need a little more height than the height of the text, so I added an extra pillow size that you can experiment with.

5) Refresh the view every time a character is typed to check if you need to increase the size:

 - (void)textViewDidChange:(UITextView *)textView { if ([self getHeightOfText:textView.text] != _textHeight) { _textHeight = [self getHeightOfText:textView.text]; [self.tableView beginUpdates]; [self.tableView endUpdates]; } } 

In this section, we get the height of the text every time the user types.

Then we use our stored value and compare the current value with the stored value. Obviously, if they are the same, it makes no sense to update the view. If they differ, we update the value and then update our table.

This bit I found a nice answer to stackOverflow showing how we can only update table heights instead of the cell itself. Why update the cell when we don’t need it? This means that as soon as it is called, the cell height is updated and it increases well.

In any case, I found that it worked very nicely and was simple enough so that it could be put together or put together different parts and put into other pieces of code.

Confirms the accepted answer, which was plundered for various objects along the way, but I also hope that this answer will help some people who are experiencing the same difficulties as me.

+3
Oct 23 '14 at 1:30
source share

I recorded my knowledge and height calculation solution based on the internal UITextView in my blog. The message contains code that works for universal applications, tabular styles and autorotations.

+2
Dec 04
source share

Finally, I started to work. The main problem is how to get the correct width of the cell contentView . Hard coding width does not work for all cases, since it can vary depending on the style of the table with a regular / grouped table, additional accessories or landscape / portrait layout. The only way to get 100% the correct width is to request it from the cell object. Therefore, I create a cell directly in heightForRowAtIndexPath and save it in the cache, then this cached cell will be returned by the cellForRowAtIndexPath method. Another problem is how to get a cell to compose its routines before using it. This can be done if we temporarily add a cell to the tableView cell and update the cell with the width of the tabelView . After that, all the subitems will be correctly drawn up. Here , how I got his work in the TableKit library.

+1
May 5 '12 at 12:27
source share

I am editing TomSwift's answer, which is the best way to do this:

here is my cell code (fast)

 class CommentaireTextViewCell: UITableViewCell,UITextViewDelegate { @IBOutlet weak var textViewCom: UITextView! weak var parentTableView:UITableView? @IBOutlet weak var constraintTextViewTopMargin: NSLayoutConstraint! @IBOutlet weak var constraintTextViewHeight: NSLayoutConstraint! @IBOutlet weak var constraintTextViewBottomMargin: NSLayoutConstraint! override func awakeFromNib() { self.textViewCom.delegate = self; } func textViewDidChange(textView: UITextView) { self.parentTableView?.beginUpdates(); self.parentTableView?.endUpdates(); } func getHeight() -> CGFloat { constraintTextViewHeight.constant = self.textViewCom.contentSize.height; // cell height = textview marge top+ textview height+ textView Marge bottom return constraintTextViewTopMargin.constant+constraintTextViewHeight.constant+constraintTextViewBottomMargin.constant+8 // add 8 because it seems to have an inset inside the textView } override func setSelected(selected: Bool, animated: Bool) { self.textViewCom.becomeFirstResponder(); } } 

for explanation, the presentation of the cell table is a weak element of the cell, so I can tell it to update the layout when the user enters text. Cell height is the sum of its upper limit for contentView, its lower limit for contentView and textView.contantSize.height, which is also equal to the constant constant textView

enter image description here

+1
Jan 6 '15 at 10:10
source share

You need to return the correct height in the delegate method heightForRowAtIndexPath.

0
Nov 21 2018-10-21
source share

Try using the following code:

 CGSize constraintSize; constraintSize.height = MAXFLOAT; constraintSize.width = yourTextView.frame.size.width; NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:@"yourFontName" size:yourFontSize], NSFontAttributeName, nil]; CGRect frame = [yourTextView.text boundingRectWithSize:constraintSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributesDictionary context:nil]; CGSize stringSize = frame.size;//The string size can be set to the UITableViewCell 
0
Mar 12 '14 at 8:32
source share

you can get the size of a UITextView programmatically. According to the size, set the cell height using the following delegate

 tableView:heightForRowAtIndexPath: 
-one
Nov 25 '10 at 17:09
source share

Guys, this is really cool stuff, but you can use tableview: didSelectRowForIndexPath: to add a UITextView to a cell, since it spies when a user deletes it, it works very well, since you only need to use 1 UITextView, which can be reused and won get in the table getting touches! Release it when done.

Details? just ask!

-2
Dec 6 '12 at 18:47
source share



All Articles