web-dev-qa-db-ja.com

iOSでステータスバーを非表示にする適切な方法、アニメーションとルートビューのサイズ変更

ボタンがクリックされたときにステータスバーをスライドアウト(または非表示)する必要があるView Controllerを考えます。

- (void) buttonClick:(id)sender
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES
                                            withAnimation:UIStatusBarAnimationSlide];
}

上記は、ステータスバーを効果的に非表示にしますが、ルートビューのサイズを適切に変更せず、上部に20ピクセルのギャップを残します。

私が期待していたのは、以前にステータスバーで使用されていたスペース(アニメーション、ステータスバーのアニメーションと同じ長さ)を拡張するルートビューです。

これを行う適切な方法は何ですか?

(同様の質問がたくさんあることは承知していますが、ステータスバーを非表示にして新しいView Controllerを表示するのではなく、オンデマンドでステータスバーを非表示にすることはできませんでした)

「ブルートフォース」アプローチ

明らかに、次の作品...

[[UIApplication sharedApplication] setStatusBarHidden:YES
                                        withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.25 animations:^{
    CGRect frame = self.view.frame;
    frame.Origin.y -= 20;
    frame.size.height += 20;
    self.view.frame = frame;
}];

...欠点があります:

  • スライドアニメーションの継続時間をハードコードします
  • ステータスバーの高さをハードコードします
  • ルートビューの原点は(0、-20)のままです。可能な限り(0,0)からフレームを開始するのが好きです。

私がすでに試したこと

  • ルートビューの自動サイズ変更マスクにUIViewAutoresizingFlexibleTopMarginおよびUIViewAutoresizingFlexibleHeightがあることを確認しました。
  • [self.view setNeedsLayout]ステータスバーを非表示にした後。
  • [self.view setNeedsDisplay]ステータスバーを非表示にした後。
  • ステータスバーを非表示にする前後にwantsFullScreenLayoutYESに設定します。
33
hpique

これは正常に機能し、何もありませんハードコーディング

CGRect appFrame = [[UIScreen mainScreen] applicationFrame];

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.25 animations:^{
    self.navigationController.navigationBar.frame = self.navigationController.navigationBar.bounds;
    self.view.window.frame = CGRectMake(0, 0, appFrame.size.width, appFrame.size.height);
}];
15
Lefteris

View Controllerベースのステータスバーの外観でこれを実装しようとしている場合は、View ControllerでprefersStatusBarHiddenメソッドを実装する必要があります

 - (BOOL)prefersStatusBarHidden
{
    // If self.statusBarHidden is TRUE, return YES. If FALSE, return NO.
    return (self.statusBarHidden) ? YES : NO;
}

そして、ボタンのクリック方法で:

- (void) buttonClick:(id)sender
{
    // Switch BOOL value
    self.statusBarHidden = (self.statusBarHidden) ? NO : YES;

    // Update the status bar
    [UIView animateWithDuration:0.25 animations:^{
        [self setNeedsStatusBarAppearanceUpdate];
    }];
}

アニメーションスタイルを設定するには、次を使用します。

-(UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
    return UIStatusBarAnimationSlide;
}

スタイルをカスタマイズするには:

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}
25
awfulcode

モーダルView Controllerを表示してから閉じて、ステータスバーを正しく非表示にすることができます

- (void)toggleStatusBar {
    BOOL isStatusBarHidden = [[UIApplication sharedApplication] isStatusBarHidden];
    [[UIApplication sharedApplication] setStatusBarHidden:!isStatusBarHidden];

    UIViewController *vc = [[UIViewController alloc] init];
    [self presentViewController:vc animated:NO completion:nil];
    [self dismissViewControllerAnimated:NO completion:nil];
    [vc release];
}

このコードを「willAnimateRotationToInterfaceOrientation」メソッドで使用して、横向きにし、すべてが正常に機能していることを確認しました。しかし、アニメーションで動作するかどうかはわかりません。

8
Exception

ビューのサイズを変更するステータスバーを表示または非表示にします。

-(void)statusBar:(BOOL)status {
UIViewController *rootViewController = self.view.window.rootViewController;
UIView *view = rootViewController.view;

// Hide/Unhide the status bar
[[UIApplication sharedApplication] setStatusBarHidden:status]; // BOOL : YES or NO

// statusBar frame
CGRect statusBarFrame = [UIApplication.sharedApplication statusBarFrame];
// Establish baseline frame
CGRect newViewFrame = self.view.window.bounds;

// Check statusBar frame is worth dodging
if (!CGRectEqualToRect(statusBarFrame, CGRectZero)) {
    UIInterfaceOrientation currentOrientation = rootViewController.interfaceOrientation;
    if (UIInterfaceOrientationIsPortrait(currentOrientation)) {
        // If portrait need to shrink height
        newViewFrame.size.height -= statusBarFrame.size.height;
        if (currentOrientation == UIInterfaceOrientationPortrait) {
            // If not upside-down move down Origin
            newViewFrame.Origin.y += statusBarFrame.size.height;
        }
    } else { // Is landscape 
        // portrait shrink width
        newViewFrame.size.width -= statusBarFrame.size.width;
        if (currentOrientation == UIInterfaceOrientationLandscapeLeft) {
            // If the status bar is on the left side of the window move Origin
            newViewFrame.Origin.x += statusBarFrame.size.width;
        }
    }
}
view.frame = newViewFrame; // pass new frame 
}

メソッドの呼び出し(メッセージ):

 if ([[UIApplication sharedApplication] isStatusBarHidden]) {
        [self statusBar:NO];
 } else {
        [self statusBar:YES];
 }
7
Shams Ahmed

便宜上、Swift @awfulcodeの答えの4つのバリアント:

var statusBarHidden = false {
    didSet {
        UIView.animate(withDuration: 0.25) {
            self.setNeedsStatusBarAppearanceUpdate()
        }
    }
}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .default
}

override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
    return .fade
}

override var prefersStatusBarHidden: Bool {
    return statusBarHidden
}
1
pinch

私はこのための方法を知っていますが、欠点も明らかです。 viewDidLoadself.wantsFullScreenLayout = YES;を設定し、画面と同じ大きさのxibファイルを設定できます(iPhone5の場合は320x480、320x568)。ただし、これは、ステータスバーの下の領域も表示されないことを意味します。また、この方法を使用すると、ステータスバーを非表示にしてもビューは拡大しません。ステータスバー領域に表示するものがない場合は、この方法を検討できます。

0
sunkehappy

実験に何時間も費やし、答えを探した後;特に この答え 。少し調整してうまくいきましたが、移行の間に20ピクセルのギャップがなくなりました!

ステータスバーを非表示にするかどうかを示すBOOL isStatusBarEnabled ivarがあるとします(たとえば、NSUserDefaultを確認するためにboolValueForKeyにアクセスする場合)。

そのため、まず[[UIApplication sharedApplication] isStatusBarHidden]を介してstatusBarがすでに非表示になっているかどうかを確認し、非表示になっていない場合(==表示されている場合)、非表示にします!そうでなければ、そうしないでください!

  • ステータスが表示されているときに20pxを修正しますが、ナビゲーションが適切にプッシュダウンされない場合は、Origin.y of self.navgigationController.navigationBar.frameに20ポイントを追加してください。

  • ステータスバーを非表示にする場合も同様に、Origin.y of self.navgigationController.navigationBar.frameの20ポイントを削除して、0のままにします。

これだよ!

@implementation SomeViewController {
    BOOL isStatusBarEnabled;
}

// ...

- (void)toggleStatusBar
{
    UINavigationBar *navBar = self.navigationController.navigationBar;

    if ([[UIApplication sharedApplication] isStatusBarHidden]) {

        // Change to regular mode
        // Show status bar
        [[UIApplication sharedApplication] setStatusBarHidden:NO
                                                withAnimation:UIStatusBarAnimationSlide];
        [UIView animateWithDuration:0.3
                         animations:^{
                             navBar.frame = CGRectMake(navBar.frame.Origin.x, 20, navBar.frame.size.width, navBar.frame.size.height);
                         } completion:nil];

    } else if (![[UIApplication sharedApplication] isStatusBarHidden]) {
        // Change to fullscreen mode
        // Hide status bar
        [[UIApplication sharedApplication] setStatusBarHidden:YES
                                                withAnimation:UIStatusBarAnimationSlide];
        [UIView animateWithDuration:0.4
                         animations:^{
                             navBar.frame = CGRectMake(navBar.frame.Origin.x, 0, navBar.frame.size.width, navBar.frame.size.height);
                         } completion:nil];
    }

}

// ...

...それから、私の場合、ユーザーがステータスバーの表示/非表示を切り替えることができるようにする設定キーがあります。

// ...

- (void)onDefaultsChanged:(NSNotification*)aNotification
{

    NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
    isStatusBarEnabled = [standardDefaults boolForKey:kStatusBar];

    if (isStatusBarEnabled) {

      if ([[UIApplication sharedApplication] isStatusBarHidden]) {

          // Change to regular mode
          // Show status bar
          [self toggleStatusBar];   

    } else {

        // Change to fullscreen mode
        // Hide status bar
        [self toggleStatusBar];

  }

  // ...
}

それでおしまい!

0
Vinh Nguyen