iPhone: прокрутить ячейку табличного представления до видимой над настраиваемой выровненной с клавиатуры панели инструментов? - PullRequest
6 голосов
/ 12 июля 2009

Я задавал вопрос или два за последние несколько дней работы над приложением, которое поддерживает настраиваемую панель инструментов в верхней части клавиатуры iPhone. Я использую метод, описанный Джошем в этом вопросе ; в основном, у меня есть контроллер вида, который прослушивает UIKeyboardWillShowNotification и добавляет панель инструментов по мере необходимости.

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

Ячейки и текстовые поля по-прежнему доступны для редактирования, но около половины ячейки скрыто под панелью инструментов. Если я исчезну с панели инструментов (не добавляю ее в автоответчик), вся ячейка станет видимой, но, очевидно, я потеряю функциональность, которую обеспечивает панель инструментов.

Есть ли способ изменить местоположение, к которому прокручивается текстовое поле? Я попытался поиграть с методом UITableView scrollToRowAtIndexPath:atScrollPosition:animated:, но он имеет тенденцию давать странные результаты при переключении между несколькими ячейками.

Каков наилучший способ прокрутки ячейки табличного представления в видимом положении над пользовательской панелью инструментов клавиатуры?

Ответы [ 4 ]

17 голосов
/ 21 июля 2009

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

Два отказа от ответственности:

  1. Я передаю parentView как часть пользовательской инициализации.
  2. Я не писал этот код, я не беру на себя ответственность за это. Я получил это от действительно замечательного блога Мэтта Галлахера Какао с любовью .

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
// adjust this following value to account for the height of your toolbar, too
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;


- (void)textFieldDidEndEditing:(UITextField *)textField
{
  CGRect viewFrame = self.parentView.frame;
  viewFrame.origin.y += animatedDistance;

  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationBeginsFromCurrentState:YES];
  [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

  [self.parentView setFrame:viewFrame];

  [UIView commitAnimations];
}

- (void) textFieldDidBeginEditing:(UITextField*) textField {
  CGRect textFieldRect = [self.parentView.window convertRect:textField.bounds fromView:textField];
  CGRect viewRect = [self.parentView.window convertRect:self.parentView.bounds fromView:self.parentView];
  CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
  CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
  CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
  CGFloat heightFraction = numerator / denominator;

  if (heightFraction < 0.0) {
    heightFraction = 0.0;
  }else if (heightFraction > 1.0) {
    heightFraction = 1.0;
  }

  animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);

  CGRect viewFrame = self.parentView.frame;
  viewFrame.origin.y -= animatedDistance;

  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationBeginsFromCurrentState:YES];
  [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

  [self.parentView setFrame:viewFrame];

  [UIView commitAnimations];
}
6 голосов
/ 23 декабря 2011

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

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    UITableViewCell *aCell = [myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:0]];
    CGSize cellSize = aCell.frame.size;
    [myTableView setContentOffset:CGPointMake(0, cellSize.height*6) animated:YES];
}       

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 
                       atScrollPosition:UITableViewScrollPositionTop 
                               animated:YES];
}

Поскольку UITableView наследуется от UIScrollView , вы можете настроить свойство contentOffset для отображения видимости строки, которая вас интересует.

В методе DidEndEditing необходимо восстановить исходную позицию прокрутки. Это достигается с помощью стандартного scrollToRowAtIndexPath: atScrollPosition: анимированный вызов.

0 голосов
/ 21 июля 2009

Поскольку все UITableView s также UIScrollView s, вы можете вызывать все стандартные методы прокрутки для них.

Что-то вроде этого подойдет:

- (void)scrollTableView:(UITableView *)tableView toIndexPath:(NSIndexPath *)indexPath withBottomPadding:(CGFloat)bottomPadding
{
    CGRect rectForRow = [tableView rectForRowAtIndexPath:indexPath];
    CGRect bounds = [tableView bounds];
    CGPoint contentOffset = [tableView contentSize];
    if (rectForRow.origin.y + rectForRow.size.height > contentOffset.y + bounds.size.height - bottomPadding)
        [tableView setContentOffset:rectForRow.origin.y + rectForRow.size.height - bounds.size.height - bottomPadding animated:YES];
    else
        [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
}

Примечание. Сейчас я не на Mac с Xcode. Я проверю этот код, когда наберу

0 голосов
/ 13 июля 2009

Может быть, вы могли бы изменить размер UITableView до высоты между панелью навигации и панелью инструментов над клавиатурой, а затем прокрутить строку в поле зрения?

...