問題
通話中にUINavigationController
(ルート ビュー コントローラーが既にプッシュされているので) を提示すると、奇妙な動作が発生することに気付きました。UIViewControllerAnimatedTransitioning
- ナビゲーション コントローラーが表示された後に通話中のステータス バーが有効になっている場合、ナビゲーション コントローラーは期待どおりにビューを下にシフトします。ただし、通話が終了しても、コントローラーはビューを上に戻さず、ステータス バーの下に 20p のギャップが残ります。
- コントローラーを表示する前に通話中ステータス バーが有効になっている場合、コントローラーはステータス バーをまったく考慮せず、高さ 44p のナビゲーション バーの 4p が 40p ステータス バーの下からはみ出します。通話が終了すると、コントローラは通常の 20p ステータス バーに合わせてビューを下に移動します。
*注: これは、通話中のステータス バーを簡単に有効/無効にできるようにシミュレーターでテストされましたが、テスターは実際の電話でこの現象を観察しました。
私の(部分的な)回避策
ステータスバーが異常な高さだった場合、プレゼンテーション中にコントローラーのフレームを調整することで問題を回避しました。
@interface CustomAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
@end
@implementation CustomAnimationController
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *container = [transitionContext containerView];
CGRect frame = [transitionContext finalFrameForViewController:toController];
if (CGRectEqualToRect(frame, CGRectZero))
{
// In my experience, the final frame is always a zero rect, so this is always hit
UIEdgeInsets insets = UIEdgeInsetsZero;
// My "solution" was to inset the container frame by the difference between the
// actual status bar height and the normal status bar height
insets.top = CGRectGetHeight([UIApplication sharedApplication].statusBarFrame) - 20;
frame = UIEdgeInsetsInsetRect(container.bounds, insets);
}
toController.view.frame = frame;
[container addSubview:toController.view];
// Perform whiz-bang animation here
}
@end
この解決策により、ナビゲーション バーがステータス バーの下にあることが保証されますが、通話が終了したときにナビゲーション コントローラーが元に戻ることはありません。したがって、アプリは少なくとも使用可能ですが、通話が終了した後、ナビゲーション バーの上に醜い 20p のギャップがあります。
より良い方法はありますか?
ナビゲーション コントローラーが通話中のステータス バーを独自に考慮していることを確認するための重要な手順がいくつかありませんか? 組み込みのモーダル プレゼンテーション スタイルで表示すると、問題なく動作します。
私の意見では、これは UIKit のバグのように見えます — 結局、ナビゲーション コントローラーはUIApplicationWillChangeStatusBarFrameNotification
(問題の 2 番目のポイントを参照) を受け取っているようです。他の誰かがこの問題に遭遇し、より良い方法を見つけた場合は、解決策をいただければ幸いです。