View Controllerの1つのステータスバーを非表示にしようとしています(モーダル表示時)。 View Controllerを表示しているとき、ステータスバーは非表示になり、終了すると戻ります。
提示されたView Controllerに次のコードを追加しました
- (BOOL)prefersStatusBarHidden
{
return YES;
}
また、Info.plistファイルのキーを次のように設定しました。
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
私の理解では、これがこの作業を行うために必要なすべてであるはずです。
UIViewControllerAnimatedTransitioning
プロトコルに準拠したプレゼンテーションを行うために、カスタムアニメーションコントローラーも使用しています。の中に animateTransition:
実装手動でprefersStatusBarHidden
を呼び出し、続いてsetNeedsStatusBarAppearanceUpdate
を呼び出して、呼び出しが行われていることを確認しようとしましたが、ステータスバーは残ります。
これがなぜ起こっているのか、どんなアイデアでも歓迎されます。 StackOverflowを検索しましたが、誰もこの問題を抱えていないようです。受け入れられたすべての回答は、すでに行っているsetNeedsStatusBarAppearanceUpdate
の呼び出しを参照しています。
[〜#〜] edit [〜#〜]-以下のコードは、今では[〜#〜] work [〜#〜]必要に応じて
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
if (self.isPresenting) {
UIView *containerView = [transitionContext containerView];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
toViewController.view.frame = containerView.frame;
[containerView addSubview:toViewController.view];
// Ask the presented controller whether to display the status bar
[toViewController setNeedsStatusBarAppearanceUpdate];
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
toViewController.view.alpha = 1.0f;
fromViewController.view.alpha = 0.0f;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
else {
// do the reverse
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
toViewController.view.alpha = 1.0f;
fromViewController.view.alpha = 0.0f;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
// Once dismissed - ask the presenting controller if the status bar should be presented
[toViewController setNeedsStatusBarAppearanceUpdate];
}];
}
}
....
// PresentingController.m
- (BOOL)prefersStatusBarHidden
{
if (self.presentedViewController) {
return YES;
}
return NO;
}
// PresentedController.m
- (BOOL)prefersStatusBarHidden
{
return YES;
}
IOS7には、実際にはmodalPresentationCapturesStatusBarAppearance
と呼ばれるUIViewControllerの新しいプロパティがあります。 Apple iOSリファレンス
デフォルト値はNOです。
PresentViewController:animated:completion:メソッドを呼び出してView Controllerを提示すると、提示されたControllerのmodalPresentationStyle値がUIModalPresentationFullScreenの場合にのみ、ステータスバーの外観制御が提示から提示されたView Controllerに転送されます。このプロパティをYESに設定することにより、フルスクリーンではない場合でも、表示されるView Controllerコントロールのステータスバーの外観を指定します。
システムは、フルスクリーンで表示されるView Controllerのこのプロパティの値を無視します。
したがって、通常のフルスクリーン以外のpresentationStyle(UIModalPresentationCustomなど)の場合、ステータスバーをキャプチャする場合は、このを設定する必要があります。使用するには、表示されているView ControllerでYES
に設定するだけです。
toVC.modalPresentationCapturesStatusBarAppearance = YES;
これは、iOS 7でカスタムトランジションを使用して表示されたView Controllerを実行するとき、古いView Controllerがまだ存在しているためだと推測します。したがって、おそらくまだ発言権があります。
ブレークポイントをitsprefersStatusBarHidden
に入れて見ることもできます。実装されていない場合は実装する必要があります。デフォルトはNOであるため、参照した場合、結果が説明されます。
私が正しい場合は、oldView ControllerのprefersStatusBarHidden
を実装して、それがあるかどうかに応じて2つの異なる答えを与える必要がありますpresentedViewController
かどうか。
[〜#〜] edit [〜#〜]これで確認しました。それは私が思ったよりもさらに悪い。私のテストでは、2番目のView ControllerのprefersStatusBarHidden
はまったく呼び出されていません。すべては、最初のView Controllerの管理下にあります。私が言ったように、最初のView Controllerがなくなることはないため、これは理にかなっています。カスタムプレゼンテーションアニメーションでは、2番目のビューコントローラーが最初のビューコントローラーに従属します。これは、2番目のビューが最初のビューの上に部分的にホバーできるためです。
したがって、最初のView Controllerから完全にステータスバーを操作する必要があります。 [self setNeedsStatusBarAppearanceUpdate]
を呼び出すことにより、prefersStatusBarHidden
を呼び出すことができます。状況に応じて異なる回答をする必要があります。これには少し注意が必要です。簡単な実装を次に示しますが、すべてのケースを網羅しているわけではありません。
// ViewController1:
-(void)setHide:(NSNumber*)yn {
self->hide = [yn boolValue]; // a BOOL ivar
[self setNeedsStatusBarAppearanceUpdate];
}
-(BOOL)prefersStatusBarHidden {
return self->hide;
}
- (IBAction)doButton:(id)sender {
self->hide = YES;
[self setNeedsStatusBarAppearanceUpdate];
[self presentViewController:[ViewController2 new] animated:YES completion:nil];
}
// ==========
// ViewController2:
- (IBAction)doButton:(id)sender {
[self.presentingViewController setValue:NO forKey:@"hide"];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
動作せず、UIViewControllerがUINavigationControllerの子である場合、このコードが解決策になる可能性があります。
open override var prefersStatusBarHidden: Bool {
return topViewController?.prefersStatusBarHidden ?? super.prefersStatusBarHidden
}
基本的に、UINavigationControllerは独自のprefersStatusBarHidden値を使用しますが、私の場合は、階層内のトップビューコントローラーのプロパティでそれを上書きしたかったのです。
これをinfo.plistに追加できます
「コントローラーベースのステータスバーの外観を表示」および値を「いいえ」に設定