Pages

2011年10月28日金曜日

iPhoneの数字キーパッドを閉じる術

iPhoneアプリでUITextFieldに入力するためにキーパッドを表示させて
入力が完了した後にキーパッドを非表示にさせるのにどんな方法を使ってますか?

iPadだとキーパッドに非表示にするためのボタンが備わってます。
iPhoneでもEnterキーがある場合には、EnterキーにDoneとかを設定しておくと
イベントセレクタ等でEnterキーの入力を受け取って非表示にしたりできます。

でもNumberPadの場合にはEnterキーがありません。
しかもキーパッドの上に完了ボタンがあったりするのって
よく見かけますよね。

私の使ってる方法を紹介します。
テストアプリを作る要領で順を追って説明してみます。

まず、Single View Applicationでプロジェクトを作成します。


InterfaceBuilder大好きで、今回も使います。
Storyboardは、まだまだ私の理解度が低いので今回は使いません。

デフォルトでできたViewController.mで@implementationのところに
UITextFieldと完了ボタンを表示するビューを宣言します。
これ、一応、私の中ではXcode4.2風の書き方です。
またこれは何かの記事で書きたいと思います。

@implementation ViewController {
  __strong IBOutlet UITextField* textField;
  __strong IBOutlet UIView* doneView;
}

それから、InterfaceBuilderの出番です。


UITextFieldを一つ置いただけです。
それと独立したビューとして完了ボタンを含んだビューを定義します。
完了ボタンはあえて似せた画像を作ってみました。
ビュー背景は黒の半透明にしてみました。

UITextFieldと完了ボタンのUIViewは、
さきほど宣言したアウトレットプロパティとリンクさせておきます。

で、完了ボタンビューを操作するためのオブザーバーを設定します。
オブザーバーの削除もちゃんと仕込んでおきます。

@interface ViewController(PrivateSelectors)
- (void)keypadDidAppear:(NSNotification*)notification;
- (void)keypadWillDisappear:(NSNotification*)notification;
@end

- (void)viewDidLoad {
  [super viewDidLoad];

  // キーパッドが表示された直後に呼び出されるセレクタを設定する。
  [
   [NSNotificationCenter defaultCenter]
   addObserver:self
   selector:@selector(keypadDidAppear:)
   name:UIKeyboardDidShowNotification
   object:nil
   ];

  // キーパッドが非表示になった直後に呼び出されるセレクタを設定する。
  [
   [NSNotificationCenter defaultCenter]
   addObserver:self selector:@selector(keypadWillDisappear:)
   name:UIKeyboardWillHideNotification
   object:nil
   ];
}

- (void)viewDidUnload {
  // オブザーバーを削除する。
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

※横スクロールで見難くなるのを避けるため、
いつもより余計に改行を入れております。
余計に見難いかもしれません・・・・・

で、keypadDidAppearがキーパッド表示直後に呼び出されますので
次のようにして完了ボタンビューをアニメーションを使って表示します。

- (void)keypadDidAppear:(NSNotification *)notification {
  // 基本のウィンドウ
  UIWindow* window = (UIWindow*)[[[UIApplication sharedApplication] windows] objectAtIndex:0];

  // キーパッドが表示される領域を取得する。
  CGRect kbRect = [
     [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey]
     CGRectValue
     ];

  // 完了ビューをキーパッドの上端に配置する。
  [window addSubview:doneView];
  doneView.frame = CGRectMake(kbRect.origin.x, kbRect.origin.y, kbRect.size.width, 37);
  doneView.hidden = NO;

  // 完了ビュー表示アニメーション
  [UIView beginAnimations:@"appear" context:nil];
  doneView.frame = CGRectOffset(doneView.frame, 0.0, -37.0);
  [UIView commitAnimations];
}

ここでは、キーパッドが表示された直後に完了ボタンビューがピョコっと
かわいく出てきます。この辺は好みでアレンジしていただいたらいいと思います。
オブザーバーもUIKeyとかもあるのでいろいろ楽しめると思います。

完了ボタンがタップされたときの処理はこんな感じ。

- (IBAction)onDoneButton:(id)sender {
  [textField resignFirstResponder];
  [self setEditing:NO animated:YES];
}

KeypadWillDisappearでは、完了ボタンビューを非表示にしているだけです。

- (void)keypadWillDisappear:(NSNotification *)notification {
  // 完了ビューを非表示にする。
  [doneView removeFromSuperview];
  doneView.hidden = YES;
}

こんな感じになります。


オブザーバーの種類は、

UIKeyboardWillShowNotification
UIKeyboardDidShowNotification
UIKeyboardWillHideNotification
UIKeyboardDidHideNotification
キーパッド情報としては、
UIKeyboardFrameBeginUserInfoKey
UIKeyboardFrameEndUserInfoKey
UIKeyboardAnimationCurveUserInfoKey
UIKeyboardAnimationDurationUserInfoKey
が用意されていますので、アレンジ次第ではかなり楽しめるのではないでしょうか?


0 コメント:

コメントを投稿