I am creating an application with iOS 7 devices. This application contains UITableView with dynamic cell height.
To create this I have a custom cell which contains methods:
- (CGFloat)heightWithModel:(Model *)model
{
CGFloat height = 0.0f;
height = self.contentLabel.frame.origin.y + [self contentHeightWithModel:model] + CellBottomOffset;
return height;
}
and...
- (CGFloat)contentHeightWithModel:(Model *)model
{
CGFloat height = 0.0;
NSDictionary *attributes = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:14.0f] forKey:NSFontAttributeName];
NSString *string = model.content;
NSStringDrawingContext *context = nil;
NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin;
CGSize size = CGSizeMake(self.contentLabel.bounds.size.width, CGFLOAT_MAX);
CGRect frame = [string boundingRectWithSize:size options:options attributes:attributes context:context];
height = frame.size.height;
return height;
}
In my view controller, I have implemented UITableViewDelegate protocol method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height;
static Cell *cell;
if (!cell)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellReuseIdentifier];
}
height = [cell heightWithModel:[self.dataSource.models objectAtIndex:indexPath.row]];
return height;
}
As far as I understand, this should be enough to create a table view with dynamic cell height. Despite this, I have a table view like this:
As you see, part of text are hidden, because label (red one) height is too small. Cell height is set dynamically by using Auto Layout (10 px from the bottom).
Can anyone see where is the problem?
First take a variable
CGFloat height;
put this lines in viewdidload method
in that set estimated height of cell and for that label set lines to 0 in inspector panel and change its height = to >= and give constraint from all side
[self.tbl_rating layoutIfNeeded];
[self.tbl_rating setNeedsLayout];
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1 )
{
self.tbl_rating.estimatedRowHeight=153.0f;
self.tbl_rating.rowHeight=UITableViewAutomaticDimension;
}
Now put this two method for finding label height and dynamic cell height increment
In this method set your label text that you retriving from like array or web service
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// 7.1>
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1 ) {
height=[self findHeightForText:[NSString stringWithFormat:#"%#",[[arr_review valueForKey:#"desc"]objectAtIndex:indexPath.row]] havingWidth:self.view.frame.size.width andFont:[UIFont systemFontOfSize:12.0f]].height;
return 153+height;
}
return UITableViewAutomaticDimension;
}
-(CGSize)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
CGSize size = CGSizeZero;
if (text) {
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{ NSFontAttributeName:font } context:nil];
size = CGSizeMake(frame.size.width, ceil(frame.size.height));
}
return size;
}
NOTE: In tableview method heightForRowAtIndexPath I recommand you pass text from array value. If this thing doesnt work then check your constraints.
This thing works for me Hope it will work.
Thank you.
Related
I want to change the height of my tableview cell according to the amount of text by using auto layout. I have tried the following code but it doesn't work:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
AddTaskDetails *addTaskDetail = (self.tasksArray)[indexPath.row];
CGFloat height;
float textcount = [addTaskDetail.taskDetail length];
if(textcount>60)
{
height = textcount-20;
NSLog(#"%d,%f",indexPath.row,height);
}
else
{
height = 70;
}
return height;
}
You better don't hardcode the height required for the string. Rather use the attributed text height property.
let attributes = [NSFontAttributeName : textFont,
NSForegroundColorAttributeName : UIColor(
red:25/255,
green:176/255,
blue:37/255,
alpha:1.0)]
let attrString:NSAttributedString? = NSAttributedString(string: yourString, attributes: attributes)
let rect:CGRect = attrString!.boundingRectWithSize(CGSizeMake(280.0,CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, context:nil )
return rect.height
You will need to use boundingRectWithSize:options:attributes:context on the string to be rendered.
This is a frequently asked question and you may find code snippets when you search for 'UITableViewCell with dynamic height'.
Try with this...
it will help you.
NSString *classSubjecttxt =#"Some text";
CGSize requiredSizeSubjetc =[classSubjecttxt sizeWithFont:[UIFont fontWithName:#"Trebuchet MS" size:12] constrainedToSize:CGSizeMake(labelwidth, CGFLOAT_MAX)];
int height=YOUR DEFAULT HEIGHT;
if(requiredSizeSubjetc.height >18){
height=height-18+ceil(requiredSizeSubjetc.height);
}
return height;
You don't have to do it programmatically. You can easily do it using Autolayouts in interface builder.
Just add a UITableViewCell to you UITableView
Set its style to custom
Make sure its size in Size inspector is default
Add a UILabel to this cell
Set its Top, Bottom, Left, Right Constraints
In size inspector set preferred width to explict
In attribute inspector set number of lines to "0"
Then add these lines in viewDidLoad()
tableView.estimatedRowHeight = 40.0
tableView.rowHeight = UITableViewAutomaticDimension
Also implement these delegate methods
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 44
}
- (CGFloat)getLabelHeight:(NSString*)textvalue
{
if (![textvalue isEqualToString:#""]) {
NSString *string=textvalue;
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
UIFont *font = [UIFont systemFontOfSize:12];
CGSize constraint = CGSizeMake(SCREENWIDTH/1.0,NSIntegerMax);
NSDictionary *attributes = #{NSFontAttributeName: font};
CGRect rect = [string boundingRectWithSize:constraint
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:attributes
context:nil];
return rect.size.height;
}
else
{
return 20;
}
}
Then You can get size by calling this :
AddTaskDetails *addTaskDetail = (self.tasksArray)[indexPath.row];
CGFloat textHeight = [self getLabelHeight:[addTaskDetail valueForKey:#"YOURKEY"]];
Here You will get the text size of your text then return it to heightForRowAtIndexPath.
First of all you need to calculate height of your label.
You can get dynamic height of your label by calling with below functions:
-(CGFloat)getDynamicHeightOfLabelWithFont:(UIFont *)font withText:(NSString *)text withFrame:(CGRect)initialFrame
{
UILabel *lblDummy = [[UILabel alloc] initWithFrame:initialFrame];
lblDummy.font = font;
lblDummy.lineBreakMode = NSLineBreakByWordWrapping;
lblDummy.numberOfLines = 0;
lblDummy.text = text;
CGRect dummyFrame = initialFrame;
dummyFrame.size = [lblDummy sizeThatFits:initialFrame.size];
return dummyFrame.size.height;
}
You need to call this function on heightForRowAtIndexPath and return the height.
and you need to set the frame on cellForRowAtIndexPath and set frame to your label.
1.Create a custom cell class. Create outlets for label/imageview.
2.Add this method in your custom cell class.
-(void) layoutSubviews
{
[super layoutSubviews];
[self.contentView layoutIfNeeded];
self.yourLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.sentenceLabel.frame);
}
3.In your view controller class,create a property of your custom cell class.
-(DynamicTblVCell *)prototypeCell
{
if(!_prototypeCell)
{
_prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:#"DynamicTblVCell"];
}
return _prototypeCell;
}
4. In your viewDidLoad add these two lines:
self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
5. And finally do this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"DynamicTblVCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
//to configure a cell before it is displayed
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}
-(void)configureCell:(UITableViewCell *)cell forRowAtIndexPath: (NSIndexPath *)indexPath
{
if([cell isKindOfClass:[DynamicTblVCell class]])
{
DynamicTblVCell * textCell = (DynamicTblVCell *)cell;
textCell.sentenceLabel.text = [NSString stringWithFormat:#"jhjshdjshdjhkjdhajsdhajsdh"];
textCell.sentenceLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
[self configureCell:self.prototypeCell forRowAtIndexPath:indexPath];
self.prototypeCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(self.prototypeCell.bounds));
[self.prototypeCell layoutIfNeeded];
CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height+1;
}
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
set number of lines for label to 0.
Add constraints for top space, bottom space, left and right space. Do not add height constraint for label.
Use below code to get better result with/without Autolayout. Need to calculate font height of label and set the position as per your requirement.
It will also helpful for calculate collectionView's dynamic cell height.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGSize constraint = CGSizeMake(screenWidth - 62, 20000.0f);
CGSize size;
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
CGSize boundingBox = [string boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:self.titleLabel.font}
context:context].size;
size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));
return size.height + 16;
}
I have a static table view that I am using as a sot of data entry for my app. One of those cells has a UITextView in it, which needs to grow and shrink dynamically as the user types, as well as the cell growing/shrinking logically with it. I read a bunch of posts on this but I think I am getting thrown because I am using a STATIC table view.
Here is my resizing attempt (its pretty much a total fail):
- (void)textViewDidChange:(UITextView *)textView
{
self.numberOfLines = (textView.contentSize.height / textView.font.lineHeight) - 1;
float height = 44.0;
height += (textView.font.lineHeight * (self.numberOfLines - 1));
CGRect textViewFrame = [textView frame];
textViewFrame.size.height = height - 10.0; //The 10 value is to retrieve the same height padding I inputed earlier when I initialized the UITextView
[textView setFrame:textViewFrame];
[self.tableView beginUpdates];
[self.tableView endUpdates];
[self.messageTextView setContentInset:UIEdgeInsetsZero];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
float height = 44.0;
if (self.messageTextView) {
height += (self.messageTextView.font.lineHeight * (self.numberOfLines - 1));
}
return height;
}
I'll take any tips! Thanks.
You don't have to do anything just go through this code:-
There is a new function to replace sizeWithFont, which is boundingRectWithSize.
Add the following function to my project, which makes use of the new function on iOS7 and the old one on iOS lower than 7. It has basically the same syntax as sizeWithFont:
-(CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
if(IOS_NEWER_OR_EQUAL_TO_7){
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
font, NSFontAttributeName,
nil];
CGRect frame = [text boundingRectWithSize:size
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:attributesDictionary
context:nil];
return frame.size;
}else{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [text sizeWithFont:font constrainedToSize:size];
#pragma clang diagnostic pop
}
}
You can add that IOS_NEWER_OR_EQUAL_TO_7 on your prefix.pch file in your project as:
#define IOS_NEWER_OR_EQUAL_TO_7 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= 7.0 )
I have referred from this link:-
UITableViewCell with UITextView height in iOS 7?
Please check my answer.
Calculate UITableViewCell height to fit string
Here label is used to calculate the height of cell.
When you done with editing of Text in textfield - (void)textViewDidEndEditing:(UITextView *)textView call the tableview reloadData function to update the cell as per text entered in textview
Your will need to manually calculate new size of you textView, and manually call update for your tableView.
static CGFloat cellHeight = 85;//from story board height to
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (indexPath.row == 0) {
return cellHeight + [self appendTextViewNewHeight];
}
return cell.bounds.size.height;
}
-(CGFloat) appendTextViewNewHeight {
return _appendHeightForTextView;
}
static CGFloat textViewHeightStartHeight = 33;//from storiboard height
- (void)textViewDidChange:(UITextView *)textView;
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
if (newFrame.size.height >= textViewHeightStartHeight) {
CGFloat newAppend = newFrame.size.height - textViewHeightStartHeight;
if (newAppend != self.appendHeightForTextView) {
self.appendHeightForTextView = newAppend;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
}
}
Also you need to set delegates on storyboards on in the code.
in viedDidLoad you need to do next things:
self.appendHeightForTextView = 0;
And finally set constraints in storyboard for your cell. Do not set bottom constraint of your textView. Only set right, left, and top.
I am working on an app which requires me to show pictures and some text in TableView. These pictures can be of different heights and so I need to vary the cell height accordingly. so I have overridden this method :
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
If I have a single static value for cell identifier then the height of the image inside the cell cannot vary dynamically.
So do I need to have different values of Cell Identifier for each cell ? Is there some other way ?
I cannot use some other view than Tableview because I need to show some cells dynamically in between based on user interaction.
Thanks.
You should reference your data model to get the image size and return the row height.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UIImage *image = dataModel[indexPath.row];
return image.size.height + 16.0; //16 is for padding
}
If you subclass your cell, you can adjust the imageView frame in -layoutsubviews (after super):
- (void)setupImageView
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.clipsToBounds = YES;
self.contentImageView = imageView;
[self.contentView addSubview:imageView];
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect bounds = self.contentView.bounds;
float margin = 8.0;
CGRect textViewFrame = CGRectZero;
textViewFrame = CGRectMake(margin, roundf(margin * 2.0), bounds.size.width - (margin * 2.0), roundf(bounds.size.height - (margin * 4.0)));
self.contentImageView.frame = textViewFrame;
}
For dynamic tableViewCell height use this.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGSize labelHeight = [self heigtForCellwithString:yourLabel.text withFont:yourLabel.font];
return labelHeight.height; // the return height + your other view height
}
-(CGSize)heigtForCellwithString:(NSString *)stringValue withFont:(UIFont)font{
CGSize constraint = CGSizeMake(300,9999); // Replace 300 with your label width
NSDictionary *attributes = #{NSFontAttributeName: font};
CGRect rect = [stringValue boundingRectWithSize:constraint
options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:attributes
context:nil];
return rect.size;
}
Example for only an image:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//get reference to a image
UIImage *image = [arrImages objectAtIndex:indexPath.row];
//get the height of your imageview on the cell
CGFloat imageViewHeight = image.size.height/2;//RetinaDisplay
//return the height of the imageview (plus some padding) for your cell height
return imageViewHeight; //add here also all other constant height's of objects that you have on your cell.
}
For a more comprehensive example look at my answer here:
Resize Custom cell with a UILabel on it based on content text from JSON file
Calculate the Cell Height
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *text = [items objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
For more reference see the Link..
You should calculate the height of each cell before the cell display.So,You could write a method to get the height,and then use the method you written in the Model.
I have a UILabel in a cell and I need to change the height of the UILabel dynamically. So the cell is a xib file with height 44 and label 240x44 and label autosizing horizontally and vertically. The font is 15.0f size, system. Number of lines = 0, wrap by word.
So I have the method
+ (CGFloat) cellHeightForString: (NSString *) string
{
CGFloat cellHeight = [string sizeWithFont:[UIFont systemFontOfSize:15.0f] constrainedToSize:CGSizeMake(240.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping].height;
return cellHeight < 44.0f ? 44.0f : cellHeight;
}
but the height of the cell is sometimes smaller so not all lines of the text are shown in the cell. Can't understand what I'm doing wrong.. Any help?
Try this,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// add your code snippet here
// dynamically change the label height,
CGSize textSize = {
200.0, // limit width
20000.0 // and height of text area
};
CGSize contentSize = [yourText sizeWithFont:[UIFont systemFontOfSize:15.0] constrainedToSize:textSize lineBreakMode:NSLineBreakByWordWrapping];
CGFloat contentHeight = contentSize.height < 36? 36: contentSize.height; // lower bound for height
CGRect labelFrame = [yourLabel frame];
yourLabel.size.height = contentHeight;
[yourLabel setFrame: labelFrame];
[yourLabel setText:yourText];
return cell;
}
Dynamically change the cell height,
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
YourCell *currentCell = (YourCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
// change hard coded value based on your cell alignment
int cellLength=[currentCell.yourLabel.text length]/42;
cellLength = cellLength*22 > 200 ? cellLength*22 : 200;
CGSize constraint = CGSizeMake((200 - 10), cellLength);
CGSize size1 = [cellText sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
return 220+size1.height;
}
I have a UITableview with multiple reusable TableViewCells.
In one cell I have a UITextView, that resizes itself to fit its content. Now I "just" have to resize the contentView of the TableViewCell, so I can read the while text. I already tried:
cell2.contentView.bounds.size.height = cell2.discriptionTextView.bounds.size.height;
Or:
cell2.contentView.frame = CGRectMake(0, cell2.discriptionTextView.bounds.origin.y,
cell2.discriptionTextView.bounds.size.width,
cell2.discriptionTextView.bounds.size.height);
In the method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {}
But it won't work.
Does anyone know how to do this?
New code:
#implementation AppDetail
CGFloat height;
…
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{…
cell2.TextView.text = self.text;
[cell2.TextView sizeToFit];
height = CGRectGetHeight(cell2.TextView.bounds);
…
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
return 143;
}
if (indexPath.row == 1) {
return height;
}
return 0;
}
You can only resize a UITableViewCell in tableView:heightForRowAtIndexPath: delegate method.
You have to estimate what the size of the text will be when that method is called for every row when the tableView is loaded.
This is what I did to solve the problem.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * yourText = self.myArrayWithTextInIt[indexPath.row]; // or however you are getting the text
return additionalSpaceNeeded + [self heightForText:yourText];
}
-(CGFloat)heightForText:(NSString *)text
{
NSInteger MAX_HEIGHT = 2000;
UITextView * textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, WIDTH_OF_TEXTVIEW, MAX_HEIGHT)];
textView.text = text;
textView.font = // your font
[textView sizeToFit];
return textView.frame.size.height;
}
EDIT
While I used this solution for a while, I found a more optimal one that I would recommend using as it doesn't require allocating an entire textView in order to work, and can handle text greater than 2000.
-(CGFloat)heightForTextViewRectWithWidth:(CGFloat)width andText:(NSString *)text
{
UIFont * font = [UIFont systemFontOfSize:12.0f];
// this returns us the size of the text for a rect but assumes 0, 0 origin
CGSize size = [text sizeWithAttributes:#{NSFontAttributeName: font}];
// so we calculate the area
CGFloat area = size.height * size.width;
CGFloat buffer = whateverExtraBufferYouNeed.0f;
// and then return the new height which is the area divided by the width
// Basically area = h * w
// area / width = h
// for w we use the width of the actual text view
return floor(area/width) + buffer;
}
As #Rob Norback said, There is something called UITableViewAutomaticDimension.
For Swift, The easiest way to resize content from UITableViewCell on the fly is to just add this.
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Here's an updated version for iOS 7+ that is cleaner (no extra method)
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIFont * font = [UIFont systemFontOfSize:15.0f];
NSString *text = [getYourTextArray objectAtIndex:indexPath.row];
CGFloat height = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width, maxHeight) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:#{NSFontAttributeName: font} context:nil].size.height;
return height + additionalHeightBuffer;
}
You need you implement heightForRowAtIndexPath.
Say that the data that is to be displayed in the textView is stored in a NSArray.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat cellheight = 30; //assuming that your TextView's origin.y is 30 and TextView is the last UI element in your cell
NSString *text = (NSString *)[textArray objectAtIndex:indexpath.row];
UIFont *font = [UIFont systemFontOfSize:14];// The font should be the same as that of your textView
CGSize constraintSize = CGSizeMake(maxWidth, CGFLOAT_MAX);// maxWidth = max width for the textView
CGSize size = [text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
cellHeight += size.height; //you can also add a cell padding if you want some space below textView
}
I favor this solution of Jure
First, set constraints of textview to be pinned with its superview (cell's contentView in this case).
Disable textView.scrollEnabled
Set
table.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = 44;
If finally, your code not works, then use this instead
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
Implement UITextViewDelegate like this:
- (void)textViewDidChange:(UITextView *)textView {
CGPoint currentOffset = self.tableView.contentOffset;
[UIView setAnimationsEnabled:NO];
[self.tableView beginUpdates];
[self.tableView endUpdates];
[UIView setAnimationsEnabled:YES];
[self.tableView setContentOffset:currentOffset animated:NO];
}
This thread has been quite a while, but in iOS 8 UITableViewAutomaticDimension was introduced. You have to set constraints from the top to the bottom of the cell like a scroll view to make this work. But after that, just add the following code to viewDidLoad():
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 122.0
Make sure your estimated height is as close as possible to the real thing otherwise you'll get some buggy scrolling.
Adding these two methods to the ViewController with UITableViewAutomaticDimension should do the trick. It has worked for me when embedding a UITextView inside of a UITableViewCell with variable length text.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
In case of UILabel subview in the UITableViewCell, I accomplished auto resize of the label just by setting the label's constraints (using storyboard, Xcode 8.3.2).
This is working since apparently the label's and the cell's default behavior is sizeToFit. Same should work for UITextView as well.