Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextView in a UITableViewCell smooth auto-resize

I have a UITextView in a UITableViewCell contentview and allow the cell to autoresize so that the entered text is fully shown - what I am trying to accomplish is an autoresizing cell like the native iOS4 Contacts app has, when you enter "notes" for contact - i.e. when the contentSize of the textView changes - I call reloadRowsAtIndexPaths and in the delegate's heightForRowAtIndexPath I provide the new height for row - this does the job, however it is not nice and smooth like the contact's app - I am almost sure Apple uses some undocumented trick in that app to make the cell's contentView expand smooth and animated without calling reloadRowsAtIndexPaths. My question is how would you suggest to implement such functionality? I hope I didn't miss any details in explanation.

like image 621
justadreamer Avatar asked Sep 20 '10 08:09

justadreamer


2 Answers

Try this code below, it will be help. You don't have to use any reload functions like reloadRowsAtIndexPaths.

// textview delegate

- (void)textViewDidChange:(UITextView *)textView {
    if (contentView.contentSize.height > contentRowHeight) {

    contentRowHeight = contentView.contentSize.height;

    [theTableView beginUpdates];
    [theTableView endUpdates];

    [contentView setFrame:CGRectMake(0, 0, 300.0, contentView.contentSize.height)];
    }
}

// tableview delegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat height;

    if (indexPath.row == 0)
        height = kTitleRowHeight;
    else 
        height = contentRowHeight;

    return height;
}
like image 52
Kang Byeonghak Avatar answered Oct 18 '22 19:10

Kang Byeonghak


I found the best way to solve this.

First off, of course, you're going to want to create your UITextView and add it to your cell's contentView. I created an instance variable of UITextView called "cellTextView" Here is the code that I used:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];

    if (!cellTextView) {
        cellTextView = [[UITextView alloc] initWithFrame:CGRectMake(5.0, 5.0, cell.bounds.size.width - 30.0, cell.bounds.size.height - 10.0)]; // I use these x and y values plus the height value for padding purposes.
    }
    [cellTextView setBackgroundColor:[UIColor clearColor]];
    [cellTextView setScrollEnabled:FALSE];
    [cellTextView setFont:[UIFont boldSystemFontOfSize:13.0]];
    [cellTextView setDelegate:self];
    [cellTextView setTextColor:[UIColor blackColor]];
    [cellTextView setContentInset:UIEdgeInsetsZero];
    [cell.contentView addSubview:cellTextView];

    return cell;
}

Then, create an int variable called numberOfLines and set the variable to 1 in your init method. Afterwards, in your textViewDelegate's textViewDidChange method, use this code:

- (void)textViewDidChange:(UITextView *)textView
{
    numberOfLines = (textView.contentSize.height / textView.font.lineHeight) - 1;

    float height = 44.0;
    height += (textView.font.lineHeight * (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];

    [cellTextView setContentInset:UIEdgeInsetsZero];
}    

Finally, paste this code into your heightForRowAtIndexPath method:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    float height = 44.0;
    if (cellTextView) {
        height += (cellTextView.font.lineHeight * (numberOfLines - 1));
    }
    return height;
}
like image 27
Hector Matos Avatar answered Oct 18 '22 20:10

Hector Matos