избегать просмотра при открытии клавиатуры из UITextView внутри UITableView с настраиваемой ячейкой

У меня есть UIViewController, который содержит UITableView с настраиваемыми ячейками, внутри ячейки находятся UILabels, пара неотредактируемых UITextView и одна редактируемая UITextView. Теперь, когда я нажимаю на один из UITextView, который находится в нижней или нижней части таблицы, UITextView закрывается клавиатурой. Я пробовал http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html, который отлично подходит для текстового поля / текстового представления, но не работает с таблицей с настраиваемой ячейкой. Любая помощь или предложения, как это сделать?


person Diffy    schedule 21.11.2011    source источник


Ответы (4)


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

  1. Самый простой и рекомендуемый способ - использовать UITableViewController вместо UIViewController, что автоматически гарантирует, что клавиатура не будет скрывать редактируемое поле (Если возможно, используйте этот подход, чтобы избежать неудобств при настройке U.I.)

  2. Если вы используете UIViewController и UITableView в качестве подпредставления. Вы можете прокручивать рамку пользовательского интерфейса, наблюдая за UIKeyboardWillShowNotification и UIKeyboardWillHideNotification

    - (void)registerForKeyboardNotifications 
    {
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(keyboardWillShow:)
                                                         name:UIKeyboardWillShowNotification object:nil]; //Posted immediately prior to the display of the keyboard
    
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(keyboardWillHide:)
                                                         name:UIKeyboardWillHideNotification object:nil]; //Posted immediately prior to the dismissal of the keyboard.
    }
    
    
    - (void)keyboardWillShow:(NSNotification *)aNotification 
    {  
        CGRect keyboardBounds = [[[aNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationBeginsFromCurrentState:YES];
    
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0); //when keyboard is up, that time just bring your text filed above the keyboard
        self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0);
    
        [self.tableView scrollToRowAtIndexPath:[self findIndexPathToScroll]
                              atScrollPosition:UITableViewScrollPositionTop
                                      animated:YES]; //findIndexPathToScroll implementation not shown
        [UIView commitAnimations];
    }
    
    - (void)keyboardWillHide:(NSNotification *)aNotification 
    {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationBeginsFromCurrentState:YES];
        self.tableView.contentInset = UIEdgeInsetsZero; //Once keyboard is hidden then bring back your table into your original position.
        self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero;
        [UIView commitAnimations];
    }
    
    • registerForKeyboardNotifications - вызывайте этот метод при загрузке UITableView, например: viewDidLoad

    • findIndexPathToScroll - (Реализация не показана) Это ваша бизнес-логика для подготовки IndexPath, где должно прокручиваться представление таблицы

    • removeObserver 'UIKeyboardWillShowNotification' и 'UIKeyboardWillHideNotification' как в dealloc, так и в viewDidUnload
person Alphonse R. Dsouza    schedule 05.12.2012

Два решения:

Предпочтительно: используйте UITableViewController вместо UIViewController, так как он автоматически гарантирует, что ваша клавиатура не скроет редактируемое поле.

Хакерский: Как чтобы UITextField двигался вверх при наличии клавиатуры?

person Till    schedule 21.11.2011
comment
ну, я не могу использовать UITableViewController, так как в этом представлении много всего, а не только UITableView. Я попробую другой. я вернусь сюда позже. - person Diffy; 21.11.2011

Простое решение. Реализуйте метод heightForFooter и позвольте ему вернуть значение (скажем) 100, и когда вы выберете ячейку в UITableView, они просто сдвинутся вверх на эту высоту, и клавиатура не закроет представление.

person Legolas    schedule 21.11.2011

Я всегда использовал для этого двойное решение.

  1. Измените размер таблицы, чтобы теперь она умещалась на меньшей площади.
  2. Прокрутите до ячейки, которую мы хотим видеть. (нам нужно было изменить размер таблицы для этого, иначе вы все равно не сможете добраться до последней пары ячеек в таблице.)

Для этого я регистрирую события отображения / скрытия клавиатуры и действую соответственно при их вызове.

- (void)keyboardWillShow:(NSNotification *)note {
    [self updateForKeyboardShowHide:note appearing:YES];
}
- (void)keyboardWillHide:(NSNotification *)note {
    [self updateForKeyboardShowHide:note appearing:NO];
}

- (void)updateForKeyboardShowHide:(NSNotification *)note appearing:(BOOL)isAppearing {
    // ignore notifications if our view isn't attached to the window
    if (self.view.window == nil)
        return;

    CGFloat directionalModifier = isAppearing?-1:1;
    CGRect keyboardBounds = [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    CGFloat animationDuration = [[note.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];

    // figure out table re-size based on keyboard
    CGFloat keyboardHeight;
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (UIInterfaceOrientationIsPortrait(orientation))
        keyboardHeight = keyboardBounds.size.height;
    else 
        keyboardHeight = keyboardBounds.size.width;

    [UIView animateWithDuration:animationDuration animations:^{
        // resize table
        CGRect newFrame = table.frame;
        newFrame.size.height += [self calculateKeyboardOffsetWithHeight:keyboardHeight] * directionalModifier;
        table.frame = newFrame;        
    }  completion:^(BOOL finished){
        // scroll to selected cell
        if (isAppearing) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:textFieldInEdit.tag inSection:0];
            [table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }
    }];
}

- (CGFloat)calulateKeyboardOffsetWithHeight:(CGFloat)keyboardHeight {
    // This depends on the size and position of your table.
    //   If your table happen to go all the way to the bottom of
    // the screen, you'll needs to adjust it's size by the whole keyboard height.
    // You might as well ditch this method and inline the value.
    return keyboardHeight;

    //   My table did not go to the bottom of the screen and the position was
    // change dynamically so and there was long boring calculation I needed to
    // do to figure out how much my table needed to shrink/grow.
}
person DBD    schedule 21.11.2011
comment
Вы забыли включить свой метод calculateKeyboardOffsetWithHeight :, без которого это не сработает. - person Adam; 19.08.2012
comment
@Adam: Я не думал, что метод нужен, но я вижу, как он может вызвать путаницу, поэтому я добавил его и объяснил. Надеюсь, это поможет. - person DBD; 20.08.2012