UIKeyboardTypeNumberPadにDoneキーを付ける手順

方法はココにある方法をほぼそのまま使って、ボタンのハイライトなんかもそれらしく設定。
ボタンはクラス変数で持って、キーボードが隠れる時の処理に UIKeyboardWillHideNotification を使ってみた。
あと、アニメーションはブロックにして completion でボタンを Superview から剥がしてる。

とにかく肝なのはボタンをどのウィンドウのどの位置に貼るか?って事で、それは前出のページでしっかり調べられているので楽チンだった。


それぞれのコードはこんな感じ。
interface部

@interface ViewController : UIViewController {
	IBOutlet UITextField *textField;
	UIButton *doneButton;
}

@end

Notification の登録

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

	//	Notification 登録
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

キーボードが現れるとき

- (void)keyboardWillShow:(NSNotification*)note
{
	// ボタン作成
	doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
	
	// ボタンのタイトル設定
	[doneButton setTitle:@"Done" forState:UIControlStateNormal];
	[doneButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
	[doneButton setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal];
	[doneButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
	[doneButton setTitleShadowColor:[UIColor darkGrayColor] forState:UIControlStateHighlighted];
	doneButton.titleLabel.shadowOffset = CGSizeMake(0, -1);
	
	// ボタンの背景設定
	[doneButton setBackgroundImage:[UIImage imageNamed:@"doneButtonNormal"] forState:UIControlStateNormal];
	[doneButton setBackgroundImage:[UIImage imageNamed:@"doneButtonHighlighted"] forState:UIControlStateHighlighted];
	
	// ボタンが押されたら doneButton を呼ぶ
	[doneButton addTarget:self action:@selector(touchDoneButton:) forControlEvents:UIControlEventTouchUpInside];
	
	// キーボードの最終表示位置と、アニメーション時間を NSNotification の userInfo から取得
	CGRect keyboardFrame = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
	CGFloat duration = [[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
	
	// ボタンもキーボードに合わせてアニメーションさせるために、最終表示位置とキーボードの高さ分だけ下のスタート位置を用意
	CGRect startFrame = CGRectMake(-3.0f, 427.0f + CGRectGetHeight(keyboardFrame), 108.0f, 53.0f);
	CGRect fixedFrame = CGRectMake(-3.0f, 427.0f, 108.0f, 53.0f);
	
	// ボタンをスタート位置に配置
	doneButton.frame = startFrame;
	
	// ボタンを張り付けるウィンドウはアプリケーションの 2 番目のウィンドウで、index=0 のサブビューにしないと角が丸くならない
	UIWindow* window = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
	[window insertSubview:doneButton atIndex:0];
	
	// アニメーションスタート
	[UIView animateWithDuration:duration
					 animations:^{
						 doneButton.frame = fixedFrame;
					 }
	 ];
}

ボタンが押されたとき

- (void)touchDoneButton:(UIButton*)sender
{
	// キーボードを非表示にします。
	[self.view endEditing:YES];
}

キーボードが消えるとき

- (void)keyboardWillHide:(NSNotification*)note {
	// ボタンを消すアニメーションの為にキーボードの最初と最後の位置、そして時間を NSNotification の userInfo から取得
	CGRect keyboardBeginFrame = [[note.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
	CGRect keyboardEndFrame = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
	CGFloat duration = [[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
	
	// キーボードの移動距離(newCenter)を計算
	CGFloat dx = keyboardEndFrame.origin.x - keyboardBeginFrame.origin.x;
	CGFloat dy = keyboardEndFrame.origin.y - keyboardBeginFrame.origin.y;
	CGPoint newCenter = CGPointMake(doneButton.center.x+dx, doneButton.center.y+dy);
	
	// キーボードの移動距離分だけボタンもアニメーションして移動後、Superview から外す
	[UIView animateWithDuration:duration
					 animations:^{
						 doneButton.center = newCenter;
					 }
					 completion:^(BOOL finished){
						 [doneButton removeFromSuperview];
					 }
	 ];
}

こんな感じで標準っぽい見た目で動いてる。
 
でも、ハイライトの時の影の付け方が違ってる…。どうしたら良いんだろう?
あ!フォントも違うか!


とりあえずサンプルコードを bitbucket に置いておいたので、サクっと動かしてみたい方はどうぞ。