Viewのローテーション通知処理を一時的に禁止する
何度か話題にしてきたカスタムなUIAlertViewだが、どうにもこうにも上手く制御できない。
- あるデリゲートメソッドが意図せず呼ばれる
- 同じデリゲートメソッドで振る舞いが変わる
- オリエンテーション(向き)変更時のUIAlerViewのリサイズ/リレイアウトが上手くいかない
一番やっかいなのはデバイスのオリエンテーションに追従してUIAlertViewを回転させて、尚かつ位置とサイズを毎回同じにすることなのだが、それが上手くいかないのだ。
何度か対策を嵩じてきたがその度に上記の不具合が出てきて、今度はその穴を潰すためのアドホックなコードを書くということを繰り返してきたのだがもう限界だ。
これ以上この問題に時間を掛ける訳には行かない状況なので、大胆に以下のように仕様を変えることにした。
-
- UIAlertViewを表示している最中だけVIewのオリエンテーションを禁止する
そもそもUIAlertViewを表示している時というのは処理の意思決定が必要な時であり、オリエンテーション変更は不要だと割り切ることにしたのである。(実際にそのように振る舞うアプリケーションがあるのも知っている)
そうと決まれば話は簡単だ。 ユーティリティに以下のようなデバイスのオリエンテーション通知を禁止/許可するクラスメソッドを用意する。
- BBDeviceUtil.m
+ (void)prohibitChangeOrientation { UIDevice* currentDevice = [UIDevice currentDevice]; while ([currentDevice isGeneratingDeviceOrientationNotifications]) [currentDevice endGeneratingDeviceOrientationNotifications]; } + (void)allowsChangeOrientation { UIDevice* currentDevice = [UIDevice currentDevice]; while (![currentDevice isGeneratingDeviceOrientationNotifications]) [currentDevice beginGeneratingDeviceOrientationNotifications]; }
処理ではこのメソッドを適宜呼び出せば良い。
- BBUIAlertView.m
- (id)initWith〜 { self.delegate = self; } - (void)show { //オリエンテーション変更通知の禁止 [BBDeviceUtil prohibitChangeOrientation]; [super show]; } - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { //オリエンテーション変更の許可 [BBDeviceUtil allowsChangeOrientation]; }
こうしておけば少なくとも表示時にはオリエンテーション変更のことは考えなくても済む。
本当はこんなことをしなくても良いように完璧なUIAlertViewを書きたかったのだが、商用アプリケーションの開発では時間の優先度が高い場合があり、実装の妥協も必要になるのは仕方が無いことだ。
しかし、そのうちきちんと書き直すぞ。