UIAlertViewの予期せぬwillPresentAlertView

UIAlertViewクラスのwillPresentAlertViewメッセージはUIAlertViewのライフサイクルをトラッキングするUIAlertViewDelegateに属しており、ダイアログが表示される直前に呼ばれる。
UIAlertViewDelegate Protocol Reference

UIAlertViewクラスはUIKitの中でもカスタマイズの要件が多いにも関わらずあまりカスタマイズできないため※、同メッセージでUIAlertViewのカスタマイズを書くことが多い。

- (void)willPresentAlertView:(UIAlertView *)alertView
{
    //UIAlertViewのカスタマイズコードを書く

    //サブビューの追加とオフセット計算

    //それに伴うUIAlertView自身のframe差分計算

    //etc...
}

これ自体は必要な処理なのだが、問題はこのメッセージが意図しないケースで呼ばれることがあることだ。

このスタックトレースではその意図しないwillPresentAlertViewの呼び出しが発生したケースである。

BBUIAlertViewはUIAlertViewを拡張しており内部にUITextFieldを配置している。スタックトレースでは配置されたUITextFiledをタッチした際にUIActionSheetを生成、表示してその後閉じた後に何故かwillPresentAlertViewが呼ばれている。

これがどうしてかが解らないし、どう止めて良いかが解らない。

先ほど書いたようにwillPresentAlertViewメッセージはUIAlertViewのカスタマイズコードを書くデリゲートであり、レイアウトオブジェクトを持たないUIAlertViewのために追加したサブビューと共にUIAlertView自身の矩形と座標を決定する大切な処理だが、ビューが表示される際に一度しか呼ばれないことを前提にしているので二度呼ばれると困るのである。

animationが発起になっている感じなのでCALayerを止める処理も書いてみたが、変わらなかった。仕方が無いので最初にレイアウトした結果(矩形とサイズ)を退避しておき、意図しない呼び出しが発生した場合は退避した矩形とサイズを設定し直している。凄く解りづらく汚いコードになるが仕方が無い。

※定義したレイアウトを流し込めるandroidのAlertDialogクラスとはえらい違いだ。(勿論androidの方が優れた設計だ)