Клавиатура в стиле iMessage в iOS-приложении - PullRequest
67 голосов
/ 16 октября 2011

Мне было интересно, можно ли повторить поведение клавиатуры iOS5 от Apple в приложении сообщений, не используя частные вызовы API. Когда вы прокручиваете клавиатуру в приложении для сообщений вниз, клавиатура падает, оставляя больше места для просмотра сообщений - попробуйте ее увидеть.

Я не смог найти ничего, что указывало бы на это, не начав прыгать через серьезные обручи, чтобы получить экземпляр Keyboard's View. И я уверен, что Apple не будет доволен этим.

В дополнение к ответу, приведенному ниже, вы можете увидеть полностью запеченный проект xcode моей реализации здесь: https://github.com/orta/iMessage-Style-Receding-Keyboard

Ответы [ 3 ]

49 голосов
/ 23 декабря 2013

В iOS 7 есть свойство keyboardDismissMode в UIScrollView.Так что просто установите его в «UIScrollViewKeyboardDismissModeInteractive», и вы получите это поведение.Работает в подклассах UIScrollView, таких как UITableView.

self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Swift 3:

tableView.keyboardDismissMode = .interactive

Или измените его в раскадровке (если он используется) в инспекторе атрибутов для вашегоUIScrollView подкласс.

23 голосов
/ 21 октября 2011

Это неполное решение, однако оно должно дать вам хорошую отправную точку.

Добавьте следующие ivars в ваш UIViewController:

CGRect        keyboardSuperFrame; // frame of keyboard when initially displayed
UIView      * keyboardSuperView;  // reference to keyboard view

Добавьте inputAccessoryView к вашему текстовому контроллеру. Я создал небольшой вид для вставки в качестве accessoryView:

accView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
accView.backgroundColor = [UIColor clearColor];
textField.inputAccessoryView = accView;

Я добавил вышеуказанный код к -(void)loadView

Зарегистрируйтесь, чтобы получать UIKeyboardDidShowNotification и UIKeyboardDidHideNotification при загрузке представления:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(keyboardWillShow:)
        name:UIKeyboardWillShowNotification
        object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(keyboardDidShow:)
        name:UIKeyboardDidShowNotification
        object:nil];
    return;
}

Добавить методы к указанным в качестве селекторов для уведомлений:

// method is called whenever the keyboard is about to be displayed
- (void)keyboardWillShow:(NSNotification *)notification
{
    // makes keyboard view visible incase it was hidden
    keyboardSuperView.hidden = NO;
    return;
}
// method is called whenever the keyboard is displayed
- (void) keyboardDidShow:(NSNotification *)note
{
    // save reference to keyboard so we can easily determine
    // if it is currently displayed
    keyboardSuperView  = textField.inputAccessoryView.superview;

    // save current frame of keyboard so we can reference the original position later
    keyboardSuperFrame = textField.inputAccessoryView.superview.frame;
    return;
}

Добавить методы для отслеживания касания и обновления вида клавиатуры:

// stops tracking touches to divider
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGRect newFrame;
    CGRect bounds = [[UIScreen mainScreen] bounds];

    newFrame = keyboardSuperFrame;
    newFrame.origin.y = bounds.size.height;  

    if ((keyboardSuperView.superview))
        if (keyboardSuperFrame.origin.y != keyboardSuperView.frame.origin.y)
            [UIView animateWithDuration:0.2
                    animations:^{keyboardSuperView.frame = newFrame;}
                    completion:^(BOOL finished){
                                keyboardSuperView.hidden = YES;
                                keyboardSuperView.frame = keyboardSuperFrame;
                                [textField resignFirstResponder]; }];
    return;
}


// updates divider view position based upon movement of touches
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch  * touch;
   CGPoint    point;
   CGFloat    updateY;

   if ((touch = [touches anyObject]))
   {
      point   = [touch locationInView:self.view];
      if ((keyboardSuperView.superview))
      {
         updateY = keyboardSuperView.frame.origin.y;
         if (point.y < keyboardSuperFrame.origin.y)
            return;
         if ((point.y > updateY) || (point.y < updateY))
            updateY = point.y;
         if (keyboardSuperView.frame.origin.y != updateY)
            keyboardSuperView.frame = CGRectMake(keyboardSuperFrame.origin.x,
                                                 point.y,
                                                 keyboardSuperFrame.size.width,
                                                 keyboardSuperFrame.size.height);
      };
   };
   return;
}

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

  • При отставке с первого ответа клавиатура возвращается в исходное положение перед тем, как соскользнуть с экрана. Чтобы сделать раскладку клавиатуры более плавной, сначала необходимо создать анимацию, чтобы убрать клавиатуру с экрана, а затем скрыть вид. Я оставлю эту часть в качестве упражнения для читателей.
  • Я проверял это только на симуляторе iOS 5 и на iPhone с iOS 5. Я не проверял это на более ранних версиях iOS.

Проект SlidingKeyboard, который я создал для проверки этой концепции, доступен на GitHub в каталоге примеров BindleKit:

https://github.com/bindle/BindleKit

Редактировать: пример обновления для устранения первого отказа от ответственности.

3 голосов
/ 17 марта 2015

Простое решение Владимира скроет клавиатуру при прокрутке пользователя вниз. Однако, чтобы завершить вопрос, касающийся iMessage, для того, чтобы TextField всегда был виден и привязан к верхней части клавиатуры, вам необходимо реализовать следующие методы:

- (UIView *) inputAccessoryView {
     // Return your textfield, buttons, etc
}

- (BOOL) canBecomeFirstResponder {
    return YES;
}

Вот хороший урок подробнее

...