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

UITextView в UITableViewCell обеспечивает плавное автоматическое изменение размера и скрывает клавиатуру на iPad, но работает на iPhone

Я внедрил пользовательский UITableViewCell, который включает UITextView, который автоматически изменяет размер, как пользовательский тип, аналогично полю "Примечания" в приложении "Контакты". Он работает правильно на моем iPhone, но когда я тестирую его в iPad, я получаю очень странное поведение: когда вы добираетесь до конца строки, клавиатура скрывается за миллисекунду, а затем снова показывает себя снова. Я бы назвал это просто причудливой ошибкой, но на самом деле это приводит к некоторой потере данных, поскольку, если вы печатаете, она теряет символ или два. Здесь мой код:

Код

// returns the proper height/size for the UITextView based on the string it contains.
// If no string, it assumes a space so that it will always have one line.
- (CGSize)textViewSize:(UITextView*)textView {
     float fudgeFactor = 16.0;
     CGSize tallerSize = CGSizeMake(textView.frame.size.width-fudgeFactor, kMaxFieldHeight);
     NSString *testString = @" ";
     if ([textView.text length] > 0) {
          testString = textView.text;
     }
     CGSize stringSize = [testString sizeWithFont:textView.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
     return stringSize;
}

// based on the proper text view size, sets the UITextView frame
- (void) setTextViewSize:(UITextView*)textView {
     CGSize stringSize = [self textViewSize:textView];
     if (stringSize.height != textView.frame.size.height) {
          [textView setFrame:CGRectMake(textView.frame.origin.x,
                                        textView.frame.origin.y,
                                        textView.frame.size.width,
                                        stringSize.height+10)];  // +10 to allow for the space above the text itself 
     }
}

// as per: https://stackoverflow.com/info/3749746/uitextview-in-a-uitableviewcell-smooth-auto-resize
- (void)textViewDidChange:(UITextView *)textView {

     [self setTextViewSize:textView]; // set proper text view size
     UIView *contentView = textView.superview;
     // (1) the padding above and below the UITextView should each be 6px, so UITextView's
     // height + 12 should equal the height of the UITableViewCell
     // (2) if they are not equal, then update the height of the UITableViewCell
     if ((textView.frame.size.height + 12.0f) != contentView.frame.size.height) {
         [myTableView beginUpdates];
         [myTableView endUpdates];

         [contentView setFrame:CGRectMake(0,
                                          0,
                                          contentView.frame.size.width,
                                          (textView.frame.size.height+12.0f))];
     }
}

- (CGFloat)tableView:(UITableView  *)tableView heightForRowAtIndexPath:(NSIndexPath  *)indexPath {
     int height;
     UITextView *textView = myTextView;
     [self setTextViewSize:textView];
     height = textView.frame.size.height + 12;
     if (height < 44) { // minimum height of 44
          height = 44;
          [textView setFrame:CGRectMake(textView.frame.origin.x,
                                        textView.frame.origin.y,
                                        textView.frame.size.width,
                                        44-12)];
      }
      return (CGFloat)height;
}

Проблемы

Итак, вот что происходит

  • Этот код работает на 100% правильно на моем iPhone и в симуляторе iPhone. Когда я печатаю текст, UITextView растет плавно, а UITableViewCell вместе с ним.
  • На симуляторе iPad, однако, он становится виноватым. Он отлично работает, когда вы печатаете на первой строке, но когда вы добираетесь до конца строки, клавиатура исчезает, а затем снова появляется сразу, поэтому, если пользователь продолжает набирать приложение, пропускает символ или два.
  • Вот некоторые дополнительные замечания о странных поведенческих поведениях, которые я заметил, которые могут помочь объяснить это:
    • Кроме того, я обнаружил, что удаление строк [myTableView beginUpdates]; [myTableView endUpdates]; в функции textViewDidChange:(UITextView *)textView заставляет UITextView правильно расти, а также не отображает и не скрывает клавиатуру, но, к сожалению, UITableViewCell не подходит к правильному высота.
    • UPDATE: Следуя этим инструкциям, теперь я могу остановить странное движение текста; но клавиатура все еще скрывается и отображается, что очень странно.

Есть ли у кого-нибудь идеи о том, как заставить клавиатуру постоянно показывать, а не скрывать и показывать, когда вы дойдете до конца строки на iPad?

P.S.: Я не заинтересован в использовании ThreeTwenty.

4b9b3361

Ответ 1

вам следует вернуть NO:

 -(BOOL) textViewShouldEndEditing:(UITextView *)textView

если вы хотите постоянно показывать клавиатуру. Вы должны обрабатывать случаи, клавиатура которых должна быть скрыта, возвращая YES к этой функции делегата.

изменить:

Я выкопал еще немного, когда вызвал [tableView endUpdates], он в основном делает 3 вещи:

  • Отключает взаимодействие пользователя с таблицей.
  • Обновляет изменения ячейки
  • Позволяет взаимодействовать с пользователем в таблицеView

Разница между SDK (платформами) заключается в методе [UIView setUserInteractionEnabled]. Поскольку UITableView не переопределяет метод setUserInteractionEnabled, он вызывается из супер (UIView).

iPhone при вызове setUserInteractionEnabled ищет личное поле _shouldResignFirstResponderWithInteractionDisabled, которое возвращает НЕТ по умолчанию, поэтому не уходит с первого ответчика (UITextView)

Но на iPad нет такой проверки AFAIK, поэтому она отбрасывает UITextView на шаг 1 и устанавливает фокус и делает его первым ответчиком на шаге 3

В принципе, textViewShouldEndEditing, который позволяет сохранять фокус, в соответствии с документами SDK, является вашим единственным вариантом ATM.

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

Ответ 2

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

Сначала создайте пользовательский UITableViewCell в IB с UITextField, помещенным в cellView. Важно установить для текстового представления scrollEnabled значение NO и autoresizingMask для гибкой ширины и гибкостиHeight.


В ViewController реализуется метод делегирования текстового представления -textViewDidChanged:, где textHeight - это переменная экземпляра с типом CGFloat и -tableViewNeedsToUpdateHeight - это настраиваемый метод, который мы определим на следующем шаге.

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat newTextHeight = [textView contentSize].height;

    if (newTextHeight != textHeight)
    {
        textHeight = newTextHeight;
        [self tableViewNeedsToUpdateHeight];
    }
}

Метод -tableViewNeedsToUpdateHeight вызывает представление таблицы beginUpdates и endUpdates, поэтому сам вид таблицы вызывает -tableView: heightForRowAtIndexPath:.

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

В представлении таблицы -tableView: heightForRowAtIndexPath: необходимо вычислить новую высоту для ячейки просмотра текста на основе textHeight.

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

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

Для лучшего удобства пользователя установите вставки содержимого представления таблицы для нижней части, например. 50,0.

Я тестировал его на iPad с iOS 4.2.1 и работал, как ожидалось.

Флориан