I create a UITableView
with different types of UITableViewCell
depending on the type of content to display. One of this is a UITableViewCell
with inside an UITextView
programmatically created in this way:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
if([current_field.tipo_campo isEqualToString:@"text_area"])
{
NSString *string = current_field.valore;
CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = ([string isEqualToString:@""]) ? 30.0f : stringSize.height+10;
UITextView *textView=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, height)];
textView.font = [UIFont systemFontOfSize:15.0];
textView.text = string;
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
textView.textColor=[UIColor blackColor];
textView.delegate = self;
textView.tag = indexPath.section;
[cell.contentView addSubview:textView];
[textView release];
return cell;
}
...
}
Since the text view is editable the cell that contains it should change its height to correctly fit the text view sizes. Initially I did this by resizing the UITextView
inside the method textViewDidChange
:, in this way:
- (void)textViewDidChange:(UITextView *)textView
{
NSInteger index = textView.tag;
Field* field = (Field*)[[self sortFields] objectAtIndex:index];
field.valore = textView.text;
[self.tableView beginUpdates];
CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;
textView.frame = frame;
newHeight = textView.contentSize.height;
[self.tableView endUpdates];
}
I save the new height of text view in a variable and then when tableView:heightForRowAtIndexPath
: method is called, I resize the cell in this way:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
if ([current_field.tipo_campo isEqualToString:@"text_area"])
{
return newHeight +10.0f;
}
else
return 44.0f;
...
}
In this way both are resized but is not done in sync, ie first the TextView
is resized and then it is resized the height of the cell, so for an instant the user see that the text view is larger than the cell. How can I fix this bad behavior?
I have created one demo for your problem, hope will help you.
My idea of solution is using AutoResizingMask
of UITextView
.
My .h file
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UITabBarDelegate, UITableViewDataSource, UITextViewDelegate>{
IBOutlet UITableView *tlbView;
float height;
}
@end
And my .m file (Includes only required methods)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
height = 44.0;
}
- (void)textViewDidChange:(UITextView *)textView{
[tlbView beginUpdates];
height = textView.contentSize.height;
[tlbView endUpdates];
}
#pragma mark - TableView datasource & delegates
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row==0) {
if (height>44.0) {
return height + 4.0;
}
}
return 44.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellIdentifier"];
UITextView *txtView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 2.0, 320.0, 40.0)];
[txtView setDelegate:self];
[txtView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; // It will automatically resize TextView as cell resizes.
txtView.backgroundColor = [UIColor yellowColor]; // Just because it is my favourite
[cell.contentView addSubview:txtView];
return cell;
}
Hope it will help you out.
To resize the cells you would use code similar to this
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSString *newText = [textView.text stringByReplacingCharactersInRange:range withString:text];
CGSize size = // calculate size of new text
CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;
textView.frame = frame;
if ((NSInteger)size.height != (NSInteger)[self tableView:nil heightForRowAtIndexPath:nil]) {
// if new size is different to old size resize cells.
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
return YES;
}
Set the TextView Frame With An Animation ..so that it syncs with the cell's animation of expanding height
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With