デバイス回転時の通知やメソッドの実行の流れ : Objective-C プログラミング

PROGRAM


デバイス回転時の通知やメソッドの実行の流れ

iPhone や iPad でデバイス回転時に UI のレイアウトを調整するプログラムを作成していたときのことでした。

キーボードを表示した際に、キーボードが邪魔をしないように入力フィールドの位置を移動させておいて、キーボードを隠した際に元に戻すというプログラムを組んでいたのですけど、デバイスを回転した際に、それを上手く制御できないことがありました。

 

キーボードの表示非表示を切り替えた際には、通知センター (NSNotificationCenter) から UIKeyboardWillShowNotification, UIKeyboardDidShowNotification, UIKeyboardHideShowNotification, UIKeyboardDidHideNotification を受け取ることが出来ますけど、この通知はデバイスを回転して、ユーザーインターフェイスが回転したときにも通知されます。

これを利用して、回転時にもキーボードによる制御は比較的簡単にできる感じでしたけど、その時に発生するイベントの順番を把握しておかないと、ユーザーインターフェイスが縦のときと横のときとがごっちゃになって、なかなか思ったような動作が実装できませんでした。

 

そこで、デバイスを回転したときにキーボードを含めた通知やメソッドの呼び出しが、どのような流れになるかを確認してみました。

iPhone 4S と iPad とをどちらも iOS 5.0 で確認してみたところ、キーボードを表示した状態で iPhone や iPad を回転させると、次のような順番で処理が遷っていく感じでした。

(iPad の分割キーボードを表示中は挙動が異なるようでしたが、それについては後述します)

まず、デバイスを回転させると UIViewController の "willRotateToInterfaceOrientation" メソッドが呼び出されます。このときはまだ、ユーザーインターフェイスは回転していない状態です。

続いて、通知センターから "UIKeyboardWillHideNotification" が通知されます。つまり、画面上ではわかりませんけど、ユーザーインターフェイスの回転前にいったんキーボードがしまわれることになるようです。

そして、通知センターから "UIKeyboardDidHideNotification" が通知されて、実質、キーボードが非表示になった様子です。

 

この後で、ユーザーインターフェイスの回転処理へと移って行くわけですけど、回転処理が行われるのに先立って、まずはキーボードの表示化意思を知らせる "UIKeyboardWillShowNotification" が通知センターから通知されました。

このときはまだ、ユーザーインターフェイスは回転していない状態なので、注意が必要です。回転後のユーザーインターフェイスの座標を操作したい場合には、ここではまだタイミング的に早い感じです。

 

続いて、デバイスが回転したことを知らせる "UIDeviceOrientationDidChangeNotification" が UIDevice から通知センター経由で通知されます。

これは、デバイス本体の方向が変化したことを知らせる通知のため、縦横に回転した場合以外にも、画面が上や下を向いたといったときにも通知が届くため、このタイミング以外にもいくつか通知が発生する場合があるので注意が必要です。

そのため、この通知を拾って処理をする場合には、回転したことで発生した通知かどうか UIDeviceOrientationIsPortrait([notification.object orientation]) などで確認する必要があるため、少し面倒な感じになりそうです。

 

この後で UIViewController の "didRotateToInterfaceOrientation" メソッドが呼び出されます。

ここで、回転後のユーザーインターフェイスを使ってのプログラムができるようになるので、UIViewController の派生クラスを使ってプログラムをしている場合には、このタイミングで処理をするのがいちばん的確でわかりやすいかもしれません。

 

こうして、ユーザーインターフェイスの回転が完了した後で、最後に "UIKeyboardDidShowNotification" が通知されてきます。

ここであれば、回転が終わった後のユーザーインターフェイスを使ってプログラミングを行うことができるので、UIViewController の外部から回転後のユーザーインターフェイスを操作するタイミングとしては、このタイミングがいちばん簡単なのかもしれません。

 

iPad で分割キーボードを使用していた場合の処理の流れ

iPad の iOS 5.0 から実装された分割キーボードを使用している場合、キーボード周りの通知のされ方が従来とは異なってくる感じです。

簡単に言うと、標準キーボードから分割キーボードにした時点で、キーボードが隠された扱いになるようです。そしてそれ以降は、分割キーボードである限り、Show 関係の通知はされずに、Hide 関係の通知だけが、キーボードの表示状態が切り替わったときに送られてくる感じです。

分割キーボードを標準キーボードにしたときには、そのタイミングで Show 関係の通知が送られてきます。

 

このあたりを整理すると、分割キーボードが表示されている状態では、上記の図の中で赤く記したものだけが呼び出されるようになる感じです。

キーボードの表示状態に合わせた処理を UIKeyboardWillShowNotification や UIKeyboardDidShowNotification を使って実装している場合には、iPad + iOS 5 の分割キーボードではそれらが呼び出されないことを念頭において、プログラムを組まないと思わぬ誤動作を生みそうです。

[ もどる ]