web-dev-qa-db-ja.com

iOSアプリのiMessageスタイル後退キーボード

プライベートAPI呼び出しを使用せずに、メッセージアプリでAppleのiOS5キーボードの動作を再現できるかどうか疑問に思っていました。メッセージアプリでキーボードを下にスクロールすると、キーボードが折りたたまれ、メッセージを表示するためのスペースが広がります。

キーボードのビューのインスタンスを取得するためにいくつかの深刻なフープを飛び越えて開始する必要がない限り、私はこれを行うことを指すものを見つけることができませんでした。そして、私はAppleがそれに満足しないだろうと確信しています。

以下の回答に加えて、ここに私の実装の完全にベイクされたxcodeプロジェクトを見ることができます: https://github.com/orta/iMessage-Style-Receding-Keyboard

67
orta

これは不完全なソリューションですが、良い出発点になるはずです。

次のivarをUIViewControllerに追加します。

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

InputAccessoryViewをテキストコントローラーに追加します。私は、accessorViewとして挿入する小さなビューを作成しました。

_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シミュレーターとiOS 5を搭載したiPhoneでのみテストしました。以前のバージョンのiOSではテストしていません。

この概念をテストするために作成したSlidingKeyboardプロジェクトは、GitHubのBindleKitのサンプルディレクトリから入手できます。

https://github.com/bindle/BindleKit

編集:最初の免責事項に対処するために例を更新します。

23
David M. Syzdek

IOS 7では、UIScrollViewにkeyboardDismissModeプロパティがあります。したがって、「UIScrollViewKeyboardDismissModeInteractive」に設定するだけで、この動作が得られます。 UITableViewなどのUIScrollViewサブクラスで機能します。

self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Swift 3:

tableView.keyboardDismissMode = .interactive

または、UIScrollViewサブクラスの属性インスペクターのストーリーボード(使用している場合)で変更します。

49

ウラジミールのシンプルなソリューションでは、ユーザーが下にスクロールするとキーボードが非表示になります。ただし、iMessageに関する質問を完了するには、TextFieldを常に表示してキーボードの上部に固定するために、次のメソッドを実装する必要があります。

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

- (BOOL) canBecomeFirstResponder {
    return YES;
}

これは良いチュートリアルです もっと細かく分解します

3
Oren