Как изменить размер UITableViewCell для его содержимого?

У меня есть UITableview с несколькими многократными таблицами TableViewCells. В одной ячейке у меня есть UITextView, который меняет размер, чтобы соответствовать его содержимому. Теперь мне просто нужно изменить размер contentView TableViewCell, чтобы я мог читать текст while. Я уже пробовал:

cell2.contentView.bounds.size.height = cell2.discriptionTextView.bounds.size.height; 

Или:

cell2.contentView.frame = CGRectMake(0, cell2.discriptionTextView.bounds.origin.y,     
cell2.discriptionTextView.bounds.size.width,     
cell2.discriptionTextView.bounds.size.height); 

В методе:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath 
*)indexPath {}  

Но это не сработает.

Кто-нибудь знает, как это сделать?

Новый код:

    @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;
    }

Ответы

Ответ 1

Вам нужно реализовать heightForRowAtIndexPath.

Скажите, что данные, которые должны отображаться в текстовом элементе, хранятся в NSArray.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 CGFloat cellheight = 30; //assuming that your TextView 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

}

Ответ 2

Вы можете изменить размер метода UITableViewCell только в tableView:heightForRowAtIndexPath:.

Вы должны оценить, какой будет размер текста, когда этот метод вызывается для каждой строки при загрузке tableView.

Это то, что я сделал для решения проблемы.

-(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;
  }

ИЗМЕНИТЬ

В то время как я использовал это решение некоторое время, я нашел более оптимальный вариант, который я бы рекомендовал использовать, поскольку он не требует выделения всего textView для работы и может обрабатывать текст больше 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;
}

Ответ 3

Здесь обновленная версия iOS 7+, более чистая (без дополнительного метода)

-(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;
    }

Ответ 4

Как сказал @Rob Norback, есть что-то, называемое UITableViewAutomaticDimension.

Для Swift самый простой способ изменить размер содержимого из UITableViewCell "на лету" - это просто добавить это.

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
     return UITableViewAutomaticDimension
}

Ответ 5

Этот поток был довольно продолжительным, но в iOS 8 UITableViewAutomaticDimension был введен. Вы должны установить ограничения сверху вниз, как прокрутка, чтобы сделать эту работу. Но после этого просто добавьте следующий код в viewDidLoad():

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 122.0

Удостоверьтесь, что ваша предполагаемая высота как можно ближе к реальной вещи, иначе вы получите прокрутку с ошибкой.

Ответ 6

Я пользуюсь это решение Jure

  • Во-первых, установите ограничения textview, которые будут закреплены с помощью своего супервизора (в этом случае содержимое cellView).
  • Отключить textView.scrollEnabled
  • Установите

    table.rowHeight = UITableViewAutomaticDimension;
    tableView.estimatedRowHeight = 44;
    

    Если, наконец, ваш код не работает, используйте вместо этого

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return UITableViewAutomaticDimension;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return 44;
    }
    
  • Внедрите UITextViewDelegate следующим образом:

    - (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];
      }
    

Ответ 7

Добавление этих двух методов в ViewController с помощью UITableViewAutomaticDimension должно сделать трюк. Он работал у меня при встраивании UITextView внутри UITableViewCell с текстом переменной длины.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

Ответ 8

В случае подпрограммы UILabel в UITableViewCell я выполнил автоматическое изменение размера метки, установив ограничения метки (используя раскадровку, Xcode 8.3.2).

Это работает, поскольку, по-видимому, метка и поведение по умолчанию ячейки - sizeToFit. То же самое должно работать и для UITextView.