Klawiatura w stylu iMessage w aplikacji na iOS

Zastanawiałem się, czy można odtworzyć zachowanie klawiatury Apple iOS5 w aplikacji wiadomości, bez użycia prywatnych wywołań API. Po przewinięciu klawiatury w aplikacji wiadomości klawiatura się zwija, pozostawiając więcej miejsca na wyświetlanie wiadomości - spróbuj to zobaczyć.

Nie mogłem znaleźć niczego, co wskazuje na to, aby to zrobić, bez konieczności przeskakiwania przez poważne obręcze, aby uzyskać instancję widoku klawiatury. I jestem pewien, że Apple nie byłbym z tego zadowolony.

Oprócz odpowiedzi podanej poniżej możesz zobaczyć w pełni upieczony projekt xcode mojej realizacji tutaj: https://github.com/orta/iMessage-Style-Receding-Keyboard

Author: orta, 2011-10-16

3 answers

Jest to rozwiązanie niekompletne, jednak powinno dać dobry punkt wyjścia.

Dodaj następujące ivars do kontrolera UIViewController:

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

Dodaj inputAccessoryView do kontrolera tekstu. Stworzyłem mały widok do wstawienia jako accessoryView:

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

Dodałem powyższy kod do -(void)loadView

Zarejestruj się, aby otrzymywać UIKeyboardDidShowNotification i UIKeyboardDidHideNotification po załadowaniu widoku:

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

Dodaj metody do podanych jako selektory dla powiadomień:

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

Dodaj metody do śledzenia i aktualizuj widok klawiatury:

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

Zastrzeżenie:

  • po rezygnacji z pierwszej odpowiedzi, klawiatura przesuwa się z powrotem do pierwotnej pozycji, zanim ześlizgnie się z ekranu. Aby klawiatura była bardziej płynna, musisz najpierw utworzyć animację, aby Przesunąć klawiaturę z ekranu, a następnie ukryć widok. Zostawię tę część jako ćwiczenie dla czytelników.
  • testowałem tylko to na symulatorze iOS 5 i na iPhonie z iOS 5. Nie testowałem tego z wcześniejszymi wersjami iOS.

Projekt SlidingKeyboard, który stworzyłem, aby przetestować tę koncepcję, jest dostępny na Githubie w katalogu examples BindleKit:

Https://github.com/bindle/BindleKit

Edit: Updating example to address first disclaimer.

 23
Author: David M. Syzdek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-21 06:20:50

W iOS 7 jest właściwość keyboardDismissMode w UIScrollView. Więc po prostu ustaw go na "UIScrollViewKeyboardDismissModeInteractive" i dostaniesz to zachowanie. Działa w podklasach UIScrollView, takich jak UITableView.

self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Swift 3:

tableView.keyboardDismissMode = .interactive

Lub zmień go w storyboard (jeśli go używasz) w Inspektorze atrybutów dla podklasy UIScrollView.

 48
Author: Vladimir Shutyuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-29 09:53:08

Proste rozwiązanie Vladimira ukryje klawiaturę podczas przewijania użytkownika w dół. Aby jednak zakończyć pytanie dotyczące iMessage, aby pole tekstowe było zawsze widoczne i zakotwiczone w górnej części klawiatury, musisz zaimplementować te metody:

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

- (BOOL) canBecomeFirstResponder {
    return YES;
}

Oto dobry tutorial rozkładanie go więcej

 3
Author: Oren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-16 22:52:47