UITextView in a UITableViewCell smooth auto-resize shows and hides keyboard on iPad, but works on iPhone

后端 未结 2 599
别那么骄傲
别那么骄傲 2020-12-07 11:02

I have implemented a custom UITableViewCell which includes a UITextView that auto-resizes as the user types, similar to the \"Notes\" field in the Contacts app. It is workin

2条回答
  •  被撕碎了的回忆
    2020-12-07 11:33

    I had the same issue for an iPad app and came up with another solution without having calculating the height of the text itself.

    First create a custom UITableViewCell in IB with an UITextField placed in the cell's contentView. It's important to set the text view's scrollEnabled to NO and the autoresizingMask to flexibleWidth and flexibleHeight.


    In the ViewController implement the text view's delegate method -textViewDidChanged: as followed, where textHeight is a instance variable with type CGFloat and -tableViewNeedsToUpdateHeight is a custom method we will define in the next step.

    - (void)textViewDidChange:(UITextView *)textView
    {
        CGFloat newTextHeight = [textView contentSize].height;
    
        if (newTextHeight != textHeight)
        {
            textHeight = newTextHeight;
            [self tableViewNeedsToUpdateHeight];
        }
    }
    

    The method -tableViewNeedsToUpdateHeight calls the table view's beginUpdates and endUpdates, so the table view itself will call the -tableView:heightForRowAtIndexPath: delegate method.

    - (void)tableViewNeedsToUpdateHeight
    {
        BOOL animationsEnabled = [UIView areAnimationsEnabled];
        [UIView setAnimationsEnabled:NO];
        [table beginUpdates];
        [table endUpdates];
        [UIView setAnimationsEnabled:animationsEnabled];
    }
    

    In the table view's -tableView:heightForRowAtIndexPath: delegate method we need to calculate the new height for the text view's cell based on the textHeight.

    First we need to resize the text view cells height to the maximum available height (after subtracting the height of all other cells in the table view). Then we check if the textHeight is bigger than the calculated height.

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {   
        CGFloat heightForRow = 44.0;
    
        if ([indexPath row] == kRowWithTextViewEmbedded)
        {
            CGFloat tableViewHeight = [tableView bounds].size.height;
            heightForRow = tableViewHeight - ((kYourTableViewsNumberOfRows - 1) * heightForRow);
    
            if (heightForRow < textHeight) 
            {
                heightForRow = textHeight;
            }
        }
    
        return heightForRow;
    }
    

    For a better user experience set the table view's content insets for bottom to e.g. 50.0.

    I've tested it on the iPad with iOS 4.2.1 and works as expected.

    Florian

提交回复
热议问题