UIViewControllerのshouldAutorotateToInterfaceOrientationメソッドをオーバーライドすると、iPhoneを横に傾けたときにUIViewのサイズを自動的に変えて横表示してくれるようになります。
ならばソフトウェアキーボードを表示させたときも自動的にUIViewのサイズを変えてくれる方法はないのか? 探してみたのですが、なかなか見つかりません。どうもUIViewのサイズを自分で変更する必要があるようです。これをやらないと、例えば、全面にUITextViewを貼りつけた状態でソフトウェアキーボードを表示させると、キーボードの背後にUITextViewがまわってしまい全体が見れなくなってしまうので困ります。
キーボードの表示・非表示は、NSNotificationCenterオブジェクトを介して行えます。UIWindowで、下記の定数が定義されています。
- UIKeyboardWillShowNotification
- UIKeyboardDidShowNotification
- UIKeyboardWillHideNotification
- UIKeyboardDidHideNotification
名前から想像つくように、キーボードが表示される前、表示された後、非表示になる前、非表示になった後を通知するために使われます。
例えば、キーボードが表示された後にkeyboardDidShowメソッド、キーボードが非表示になった後にkeyboardDidHideメソッドを呼び出すには、こんな感じのコードを書きます。実際には、UIViewControllerのviewDidLoadの中で書くことになるでしょう。
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
このようにすると、keyboardDidShowメソッドでは、受け取ったNSNotificationオブジェクトのuserInfoを介して様々な情報を取得することができます。例えばキーボードが表示された後のサイズは、UIKeyboardFrameEndUserInfoKeyキーを指定して取得できます。ただし、ここで得られた座標は、convertRect:fromWindow:メソッドを使ってWindowの座標に変換する必要があります。さらに、UINavigationControllerを使っていてツールバーを下部に表示している場合にはそのサイズも考慮する必要があります。具体的には、こんな感じになりますが実際にはアプリケーションごとに変わってくると思います。
- (void)keyboardDidShow:(NSNotification *)aNotification
{
CGRect keyboardRect = [self.view
convertRect:[[[aNotification userInfo]
objectForKey:UIKeyboardFrameEndUserInfoKey]
CGRectValue]
toView:nil];
CGRect viewRect = self.view.frame;
viewRect.size.height -= (keyboardRect.size.height
- self.navigationController.toolbar.frame.size.height);
self.view.frame = viewRect;
}
keyboardDidHideメソッドもほとんど同じです。上記ではviewRectからキーボードで隠れる分を引いていますが、keyboardDidHideメソッドではそれを逆に足すだけです。
通知が不要になったら、忘れずに登録を解除しましょう。viewDidUnloadなどに書いておけばよいでしょう。
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:UIKeyboardDidHideNotification
object:nil];
以上で、キーボードに追従してUIViewのサイズが変わるようになります。画面を回転しても、そのたびにキーボードの非表示→表示の通知が来るので、適切にUIViewのサイズが変更されます。