2012年10月30日 火曜日 HOME > Objective-C
【Objective-C】iOS 6.0で注意しておきたい日本語キーボードの不具合と変更点
iOS 6.0特有のもので、次期アップデートで改善されることも予想されますが、アプリへの影響が出る可能性もあるので、その内容を共有したいと思います。
1. キーボード上部に日本語の変換候補が出るとエラー大量発生
iPhoneでは、iOS 5.0 でキーボード一体型になった変換候補欄。iOS 6.0からは、始めから出ているのではなく、キーボード入力後に初めて出る形になりました。
この候補欄に不具合があるのか、変換候補が上部に出た瞬間に大量のエラーが出力されます。アプリへの直接的な影響は今のところわかりませんが、あまり気持ちの良いものではなく、今のところこちらで出来る対応策も確認できていません。
CGContext周りのエラーが大量発生
<Error>: CGContextSaveGState: invalid context 0x0
<Error>: CGContextDrawLinearGradient: invalid context 0x0
<Error>: CGContextSetFillColorWithColor: invalid context 0x0
<Error>: CGContextFillRects: invalid context 0x0
<Error>: CGContextFillRects: invalid context 0x0
(以下略)
上部に候補欄の出ない、4インチのテンキーキーボードLnadscapeではこのエラーは出力されません。上部に変換候補が出る中国語のキーボード等も出るのを確認しました。
2. 日本語の変換候補を出したままスリープするとアプリが強制終了
キーボードで何かを打ち、変換候補の欄が出た状態のまま、電源ボタンで強制的に、もしくは自然にスリープすると、アプリがクラッシュしてしまいます。
例えばメモアプリなどでは、リアルタイムにデータを保存しておかないと、せっかく入力していたデータが消えてしまっていると言うことも。
ゲームなら、プレイ中に何か入力していて、少し他に手を取られスリープしてしまったら最初から…。考えてみると様々な悪影響が考えられます。
状況や現状での解決方法などは以下が参考になります。
3. デバイス回転時キーボードのサイズが正確に取得できない場合が
NSNotificationCenter を使うと、キーボードの表示変更に伴い、その通知を受け取ることが出来ます。iOS 5.0から日本語の変換候補分キーボードの高さが変わり、対応に追われて使った人も多いのではないでしょうか。
以下のようなサンプルと全く同じ方法でやっている場合は注意が必要です。
//起動時などで、通知するように登録 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; //通知された際に呼ばれる内容 - (void)onKeyboardDidShow:(NSNotification*)notification { //キーボードのCGRect CGRect keyboardRect = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; //以下 keyboardRect を使って再配置など }
まず参考までに、PortraitからLandscapeへのデバイス回転時に通知される順番は以下の通りです。(iPhone シミュレータで確認。赤字はiOS 4.3から共通)
- iOS 4.3
- UIKeyboardWillHideNotification
- UIKeyboardDidHideNotification
- UIKeyboardWillShowNotification
- UIKeyboardDidShowNotification
- iOS 5.0
- UIKeyboardWillChangeFrameNotification
- UIKeyboardWillHideNotification
- UIKeyboardDidHideNotification
- UIKeyboardWillChangeFrameNotification
- UIKeyboardWillShowNotification
- UIKeyboardDidShowNotification
- iOS 5.1
- UIKeyboardWillHideNotification
- UIKeyboardDidHideNotification
- UIKeyboardWillShowNotification
- UIKeyboardDidShowNotification
- iOS 6.0
- UIKeyboardWillChangeFrameNotification
- UIKeyboardWillHideNotification
- UIKeyboardDidChangeFrameNotification
- UIKeyboardDidHideNotification
- UIKeyboardWillChangeFrameNotification
- UIKeyboardWillShowNotification
- UIKeyboardDidChangeFrameNotification
- UIKeyboardDidShowNotification
UIKeyboardWillShowNotification か UIKeyboardDidShowNotification 辺りを使ってサイズを取得、それに応じたUI部品の再配置など。上記比較を見ても、iOS 6.0でも大丈夫そうに見えます。
実際iOS 6.0でもほとんどの場合大丈夫なのですが、例外があります。4インチディスプレイで日本語テンキーキーボード使用時に、変換候補を出した状態で回転した際という、特殊な状況下です。(Portrait ⇔ Landscape時)
UIKeyboardDidShowNotification では、デバイス回転時に、この変換候補欄の高さ変更が反映されていないのです。最後に呼ばれるのに…、まさに罠です。
4インチディスプレイの日本語テンキーキーボードでは、Portraitでは変換候補が上部に、Landscapeでは変換候補が左に出る形になっているのですが、ここがうまく考慮できていないようです。変換候補の部分が後から出現するのが今までの設計に影響を及ぼしたのかもしれません。
なので、iOS 6.0では UIKeyboardDidChangeFrameNotification でサイズを取得する必要がありそうです。(こっちは反映されている)
iOS 6.0において、キーボード出現時、非表示にした際、キーボードの高さに変更があった場合、といった考えられる状況全てに呼ばれるのを確認したので、OSバージョンに合わせて決めうちでやるのが良いのかもしれません。
最後に
こう書いてみると、大半が変換候補周りから出た不具合という風に見て取れます。
一応Appleへバグレポートは送ってみましたが、うまく伝わっているかはわからず。確認できた方は是非バグレポートを送ってみて下さい。→ Bug Reporting
「うちはキーボードなんて使うアプリじゃないから…」なんて思っていても、SNSと連携(投稿編集機能がある)など、見落としてる場合もあるので注意です。
何か指摘や別途解決方法があったら@dice_sまでお願いします。