Подтвердить что ты не робот

Как сделать UITableViewCell с UITextView внутри, который динамически регулирует его высоту на основе UITextView?

Я хотел бы иметь представление tablew с поведением, аналогичным приложению iPhone Contacts от Apple: uitableviewcell с uitextview внутри, так что, когда я пишу в uitextview, uitextview увеличивает его высоту, и поэтому соответственно uitableviewcell динамически регулирует ее высоту. Я просматривал всю сеть, находя только частичные решения и отсутствие образца кода!

Пожалуйста, помогите мне Я в отчаянии

Тони

4b9b3361

Ответ 1

Глядя на это, вы должны быть несколько сложными. Вам нужно рассчитать высоту textView динамически и на основе высоты TextView, вам нужно вернуть высоту для ячейки.

Это очень легко и несколько Tricky.

Это код, по которому вы можете рассчитать размер строки....

Сначала получите размер строки

NSString *label =  @"Sample String to get the Size for the textView Will definitely work ";
CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15]
                      constrainedToSize:CGSizeMake(320, 9999)
                          lineBreakMode:UILineBreakModeWordWrap];

over here ....
NSLog(@"%f",stringSize.height);

Во-вторых, динамически создайте textView в ячейке. передайте stringSize.height

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    //if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    //}

    NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section];

    NSString *string = [d valueForKey:@"Description"];
    CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap];

    UITextView *textV=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, stringSize.height+10)];
    textV.font = [UIFont systemFontOfSize:15.0];
    textV.text=string;
    textV.textColor=[UIColor blackColor];
    textV.editable=NO;
    [cell.contentView addSubview:textV];
    [textV release];

    return cell;
}


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

    NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section];
    NSString *label =  [d valueForKey:@"Description"];
    CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15]
                          constrainedToSize:CGSizeMake(320, 9999) 
                              lineBreakMode:UILineBreakModeWordWrap];

    return stringSize.height+25;

} 

После того, как мои пальцы так сильно пострадали, я думаю, что этого достаточно кода... & безусловно, поможет решить вашу проблему.

Удача

Ответ 2

Создайте пользовательский UITableViewCell и добавьте UITextView в элемент содержимого cellView.

В LayoutSubviews установите textView.frame в ячейку contentView.bounds(или выполните другой пользовательский макет).

Когда содержимое textView изменяется (открывается через UITextViewDelegate), выполните две вещи:

1) call [tableView beginUpdates]; [tableView endUpdates]; Это заставит представление таблицы пересчитать высоту для всех ячеек (вызовет tableView:heightForRowAtIndexPath:). Если ваша ячейка является делегатом для textView, вам нужно выяснить, как получить указатель на tableView, но есть несколько способов добиться этого. Или вы можете сделать делегата вашим контроллером просмотра...

2), когда для этой ячейки вызывается tableView:heightForRowAtIndexPath:, верните textView.contentSize.height. Вы можете получить свою ячейку отсюда, вызвав [tableView cellForRowAtIndexPath]; Или, если у вас есть только одна из этих ячеек, затем кешируйте указатель на нее в вашем диспетчере viewController.

Ответ 3

Единственная проблема, с которой я столкнулся с принятым ответом, заключалась в том, что мы распределяем UITextView каждый раз. Я обнаружил, что это вызвало проблемы с вводом в представление и немедленным обновлением текста, а также сохранением представления в качестве первого ответчика. Когда я попытался перезагрузить ячейку новой высотой, она попыталась бы добавить новый текстовый элемент.

Из-за этого я нашел несколько иной метод для достижения той же цели. Надеюсь, это другое решение может помочь людям, которые пытаются реализовать вышеуказанный код.

1) В файле заголовка укажите переменную для высоты текста и textView:

UITextView * _textView;
NSInteger _textHeight;

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

2) Загрузите текстовое представление и добавьте его в нашу ячейку

_textView = [[UITextView alloc] init];
_textView.delegate = self;
_textView.returnKeyType = UIReturnKeyDone;
_textView.font = [UIFont fontWithName:@"Helvetica" size:16];

if (![_user metaStringForKey:bBioKey].length) {
    _textView.text = @"Placeholder text";
    _textView.textColor = [UIColor lightGrayColor];
}


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

    if (indexPath == 0) { // Add logic to choose the correct cell

        if (_textView.superview != cell) {

            [cell addSubview:_textView];     

            _textView.keepTopInset.equal = KeepRequired(7);
            _textView.keepBottomInset.equal = KeepRequired(7);
            _textView.keepRightInset.equal = KeepRequired(10);
            _textView.keepLeftInset.equal = KeepRequired(70);
            }
        }
    }
}

Использование keeplayout позволило нам сохранить наше текстовое поле всегда на той же высоте, что и ячейка. Мы также добавляем только UITextView один раз.

3) Добавьте код, чтобы рассчитать высоту текста

- (NSInteger)getHeightOfBio: (NSString *)text {

    UILabel * gettingSizeLabel = [[UILabel alloc] init];
    gettingSizeLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    gettingSizeLabel.text = text;
    gettingSizeLabel.numberOfLines = 0;
    CGSize maximumLabelSize = CGSizeMake(240, 9999); // this width will be as per your requirement

    CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

    return expectedSize.height;
}

Я пробовал много и нашел, что это работает лучше

4) Добавьте некоторую логику в высоту ячейки, чтобы использовать это:

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

    if (indexPath.row == 0) { // Set the height for our changing textView

        return 30 + [self getHeightOfBio:_textView.text];
    }

    return 44;
}

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

5) Обновляйте представление каждый раз, когда набирается символ, чтобы проверить, нужно ли увеличивать размер:

- (void)textViewDidChange:(UITextView *)textView {

    if ([self getHeightOfText:textView.text] != _textHeight) {

       _textHeight = [self getHeightOfText:textView.text];

       [self.tableView beginUpdates];
       [self.tableView endUpdates];
    }
}

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

Затем мы используем наше сохраненное значение и сравниваем текущее значение с сохраненным значением. Очевидно, что если они одинаковы, нет смысла обновлять представление. Если они отличаются, мы обновляем значение, а затем обновляем нашу таблицу.

Этот бит я нашел хороший ответ на stackOverflow, показывающий, как мы можем обновлять только высоты таблицы вместо самой ячейки. Зачем обновлять ячейку, когда нам это не нужно? Это означает, что, как только это называется, высота ячейки обновляется, и она увеличивается хорошо.

В любом случае, я нашел, что это сработало очень красиво и было достаточно простым, чтобы его можно было собрать вместе или собрать разные части и поместить в другие фрагменты кода.

Подтверждает принятый ответ, который был разграблен для разных предметов по пути, но я также надеюсь, что этот ответ поможет некоторым людям, которые испытывают те же трудности, что и я.

Ответ 4

Я записал свои знания и решение для расчета высоты , основанной на внутреннем UITextView в моем блоге. Сообщение содержит код, который работает для универсальных приложений, стилей табличного вида и авторотации.

Ответ 5

Наконец, я начал работать. Основная проблема заключается в том, как получить правильную ширину ячейки contentView. Ширина жесткого кодирования не работает для всех случаев, так как она может варьироваться в зависимости от стиля таблицы с обычным/сгруппированным столом, дополнительных аксессуаров или ландшафтной/портретной компоновки. Единственный способ получить 100% правильную ширину - это запросить его у объекта ячейки. Поэтому я создаю ячейку прямо в heightForRowAtIndexPath и сохраняю ее в кеше, тогда эта кэшированная ячейка будет возвращена методом cellForRowAtIndexPath. Другая проблема заключается в том, как заставить ячейку компоновать свои подпрограммы до ее использования. Это можно сделать, если мы временно добавим ячейку в ячейку tableView и обновим ячейку с шириной tabelView. После этого все подпункты будут правильно оформлены. Здесь, как я получил его работу в TableKit библиотека.

Ответ 6

Я редактирую ответ TomSwift, который является лучшим способом сделать это:

вот мой код ячейки (быстро)

class CommentaireTextViewCell: UITableViewCell,UITextViewDelegate {

@IBOutlet weak var textViewCom: UITextView!
weak var parentTableView:UITableView?

@IBOutlet weak var constraintTextViewTopMargin: NSLayoutConstraint!
@IBOutlet weak var constraintTextViewHeight: NSLayoutConstraint!
@IBOutlet weak var constraintTextViewBottomMargin: NSLayoutConstraint!
override func awakeFromNib() {
    self.textViewCom.delegate = self;
}

func textViewDidChange(textView: UITextView) {
    self.parentTableView?.beginUpdates();
    self.parentTableView?.endUpdates();
}

func getHeight() -> CGFloat
{
    constraintTextViewHeight.constant = self.textViewCom.contentSize.height;
    // cell height = textview marge top+ textview height+ textView Marge bottom
    return constraintTextViewTopMargin.constant+constraintTextViewHeight.constant+constraintTextViewBottomMargin.constant+8
    // add 8 because it seems to have an inset inside the textView
}

override func setSelected(selected: Bool, animated: Bool) {
    self.textViewCom.becomeFirstResponder();
}
}

для объяснения, представление таблицы ячеек является слабым элементом ячейки, поэтому я могу сказать ему обновить макет, когда пользователь вводит текст. Высота ячейки - это сумма ее верхнего ограничения для contentView, ее нижнее ограничение для contentView и textView.contantSize.height, которое также равно постоянной константе textView

enter image description here

Ответ 7

Вам нужно вернуть правильную высоту в методе делегата heightForRowAtIndexPath.

Ответ 8

Попробуйте использовать следующий код:

CGSize constraintSize;
constraintSize.height = MAXFLOAT;
constraintSize.width = yourTextView.frame.size.width;
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [UIFont fontWithName:@"yourFontName" size:yourFontSize], NSFontAttributeName,
                                      nil];

CGRect frame = [yourTextView.text boundingRectWithSize:constraintSize
                                  options:NSStringDrawingUsesLineFragmentOrigin
                               attributes:attributesDictionary
                                  context:nil];

CGSize stringSize = frame.size;//The string size can be set to the UITableViewCell

Ответ 9

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

tableView:heightForRowAtIndexPath:

Ответ 10

Ребята, это действительно классный материал, но вы можете использовать tableview: didSelectRowForIndexPath: чтобы добавить UITextView в ячейку, поскольку она подсматривает, когда пользователь ее удаляет, работает очень хорошо, так как вам нужно использовать только 1 UITextView, который можно повторно использовать и выиграть Не вмешивайся в стол, получая прикосновения! Отпустите его, когда закончите.

Детали? просто спросите!