293

iOS 7 ではUIStatusBar、次のようにビューと結合するように設計されています。

Tina Tavčar によって設計された GUI( Tina Tavčar によって設計された GUI )

  • クールですが、ビューの上部に何かがあるとビューが混乱し、ステータス バーと重なって表示されます。

  • [重複しない]動作方法をiOS6の方法に戻すことができる簡単な解決策(info.plistでプロパティを設定するなど)はありますか?

  • より簡単な解決策は、self.view.center.xビューコントローラーごとに+ 20ポイントを設定することですが、それらを変更すると他のディメンションが台無しになり(別の設定をするとself.view.center.x、カスタムセグエなどに問題が発生する可能性があります)、突然、面倒な作業に変わります.避けるのが一番。

  • 誰かがこれに対するワンライナーソリューションを提供してくれたら本当にうれしいです。

PS次のようなことを行うことでステータスバーを非表示にできることを知っています

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

方法ですが、それdidFinishLaunchingWithOptionsは回避策であり、問​​題を回避するショートカットであるため、実際の解決策とは考えていません。

4

25 に答える 25

448

これは私が書いたブログ投稿からクロスポストされたものですが、iOS 7 のステータス バー、ナビゲーション バー、およびコンテナー ビュー コントローラーの完全な概要は次のとおりです。

  1. iOS 6 スタイルのステータス バー レイアウトを保持する方法はありません。iOS 7 では、ステータス バーが常にアプリケーションに重なって表示されます。

  2. ステータス バーの外観とステータス バーのレイアウトを混同しないでください。外観 (ライトまたはデフォルト) は、ステータス バーのレイアウト (フレーム/高さ/オーバーラップ) には影響しません。システム ステータス バーの背景色がなくなったことにも注意してください。API が UIStatusBarStyleLightContent を参照する場合、それらは明確な背景に白いテキストを意味します。UIStatusBarStyleDefault は、クリアな背景に黒のテキストです。

  3. ステータス バーの外観は、相互に排他的な 2 つの基本パスのいずれかに沿って制御されます。従来の方法でプログラムで設定するか、UIViewController のいくつかの新しいプロパティに基づいて UIKit が外観を更新します。後者のオプションはデフォルトでオンになっています。"ViewController-Based Status Bar Appearance" のアプリの plist 値をチェックして、どちらを使用しているかを確認します。この値を YES に設定すると、アプリ内のすべての最上位のビュー コントローラー (標準の UIKit コンテナー ビュー コントローラーを除く) は、preferredStatusBarStyle をオーバーライドして、デフォルトまたはライト スタイルのいずれかを返す必要があります。plist 値を NO に編集すると、使い慣れた UIApplication メソッドを使用してステータス バーの外観を管理できます。

  4. UINavigationController は、やや奇妙で文書化されていない一連の制約に応じて、UINavigationBar の高さを 44 ポイントまたは 64 ポイントに変更します。UINavigationController は、ビューのフレームの上部が UIWindow の上部と視覚的に連続していることを検出すると、高さ 64 ポイントのナビゲーション バーを描画します。ビューの上部が UIWindow の上部と連続していない場合 (たとえ 1 ポイントだけずれていても)、44 ポイントの高さで「従来の」方法でナビゲーション バーを描画します。このロジックは、アプリケーションのビュー コントローラー階層内に複数の子がある場合でも、UINavigationController によって実行されます。この動作を防ぐ方法はありません。

  5. 高さがわずか 44 ポイント (88 ピクセル) のカスタム ナビゲーション バーの背景画像を指定し、UINavigationController のビューの境界が UIWindow の境界と一致する場合 (#4 で説明)、UINavigationController はフレーム (0,20,320 ,44)、カスタム イメージの上に 20 ポイントの不透明な黒いスペースを残します。これにより、ルール 1 を回避した賢い開発者だと思い込んで混乱するかもしれませんが、それは間違いです。ナビゲーション バーの高さは 64 ポイントのままです。Slide-to-reveal スタイルのビュー階層に UINavigationController を埋め込むと、これが非常に明確になります。

  6. UIViewController の edgeForExtendedLayout プロパティの紛らわしい名前に注意してください。ほとんどの場合、edgesForExtendedLayout を調整しても何も起こりません。UIKit がこのプロパティを使用する唯一の方法は、View Controller を UINavigationController に追加する場合です。UINavigationController は、edgesForExtendedLayout を使用して、子ビュー コントローラーをナビゲーション バー/ステータス バー領域の下に表示するかどうかを決定します。UINavigationController 自体に edgeForExtendedLayout を設定しても、UINavigationController に 44 ポイントまたは 64 ポイントの高さのナビゲーション バー領域があるかどうかは変わりません。そのロジックについては、#4 を参照してください。ツールバーまたは UITabBarController を使用する場合、同様のレイアウト ロジックがビューの下部に適用されます。

  7. UINavigationController 内でカスタムの子ビュー コントローラーがナビゲーション バーの下に重ならないようにするだけの場合は、edgesForExtendedLayout を UIRectEdgeNone (または少なくとも UIRectEdgeTop を除外するマスク) に設定します。この値は、View Controller のライフサイクルのできるだけ早い段階で設定してください。

  8. UINavigationController と UITabBarController は、サブビュー階層のテーブル ビューとコレクション ビューの contentInsets もパディングしようとします。これは、#4 のステータス バー ロジックと同様の方法で行われます。テーブルビューとコレクションビューに対してautomaticAdjustsScrollViewInsetsをNOに設定することで、これを防ぐプログラム的な方法があります(デフォルトはYESです)。ツールバーとキーボードの動きに応じて、contentInset 調整を使用してテーブル ビューのレイアウトを制御するため、これは Whisper と Riposte に深刻な問題を引き起こしました。

  9. 繰り返しますが、iOS 6 スタイルのステータス バー レイアウト ロジックに戻る方法はありません。これを近似するには、アプリのすべてのビュー コントローラーを、画面の上部から 20 ポイント離れたコンテナー ビューに移動し、ステータス バーの後ろに意図的に黒いビューを残して、古い外観をシミュレートする必要があります。これは、最終的に Riposte と Whisper で使用した方法です。

  10. Apple は、ユーザーが #9 を実行しようとしないことを確実にするために、非常に強く求めています。彼らは、ステータス バーの下に重なるようにすべてのアプリを再設計することを望んでいます。ただし、ユーザー エクスペリエンスと技術的な理由の両方から、これが必ずしも良い考えではない理由について、多くの説得力のある議論があります。単にプラットフォームの気まぐれに従うのではなく、ユーザーにとって最善のことを行う必要があります。

于 2013-09-17T16:49:18.063 に答える
123

2013 年 9 月 19 日の更新:

追加によるスケーリングのバグを修正 self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);

NSNotificationCenter発言の誤字を修正


2013 年 9 月 12 日の更新:

UIViewControllerBasedStatusBarAppearanceに修正NO

画面回転のあるアプリのソリューションを追加

ステータスバーの背景色を変更する方法を追加しました。


どうやら、iOS7 のステータス バーを iOS6 での動作に戻す方法はないようです。

ただし、いつでもいくつかのコードを記述して、ステータス バーを iOS6 風に変えることができます。これが私が思いつく最短の方法です。

  1. in にUIViewControllerBasedStatusBarAppearance設定( UIApplicationstatusBarStyle メソッドを使用してステータス バーのスタイルを設定できるように、View Controller でステータス バーのスタイルを調整することをオプトアウトするには)。NOinfo.plist

  2. AppDelegate のapplication:didFinishLaunchingWithOptionsで、呼び出します

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        [application setStatusBarStyle:UIStatusBarStyleLightContent];
        self.window.clipsToBounds =YES;
        self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
    
        //Added on 19th Sep 2013
        self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
    }
    return YES;
    


そうするには:

  1. iOS 7 かどうかを確認します。

  2. UIStatusBarStyleDefault ではなく、ステータス バーのコンテンツを白に設定します。

  3. フレームが表示されている境界を超えて拡張しているサブビューが表示されないようにします (上からメイン ビューにアニメーション化するビューの場合)。

  4. アプリのウィンドウ フレームを移動およびサイズ変更することで、iOS 6 のようにステータス バーがスペースを占めるように錯覚させます。


画面回転のあるアプリの場合、

NSNotificationCenter を使用して、追加することで向きの変化を検出します

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];

if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)、AppDelegate に新しいメソッドを作成します。

- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
    int a = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
    int w = [[UIScreen mainScreen] bounds].size.width;
    int h = [[UIScreen mainScreen] bounds].size.height;
    switch(a){
        case 4:
            self.window.frame =  CGRectMake(0,20,w,h);
            break;
        case 3:
            self.window.frame =  CGRectMake(-20,0,w-20,h+20);
            break;
        case 2:
            self.window.frame =  CGRectMake(0,-20,w,h);
            break;
        case 1:
           self.window.frame =  CGRectMake(20,0,w-20,h+20);
    }
}

そのため、向きが変わると、アプリの画面の向き (縦、逆さま、横左、または横右) を検出するための switch ステートメントがトリガーされ、アプリのウィンドウ フレームがそれぞれ変更され、iOS 6 のステータス バー イリュージョンが作成されます。


ステータス バーの背景色を変更するには:

追加

 @property (retain, nonatomic) UIWindow *background;

でクラスにプロパティAppDelegate.hを作成backgroundし、ARC がその割り当てを解除しないようにします。(ARC を使用していない場合は、これを行う必要はありません。)

その後、次のように UIWindow を作成する必要がありますif (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)

background = [[UIWindow alloc] initWithFrame: CGRectMake(0, 0, self.window.frame.size.width, 20)];
background.backgroundColor =[UIColor redColor];
[background setHidden:NO];

@synthesize background;後を忘れないでください@implementation AppDelegate

于 2013-08-22T17:38:04.533 に答える
41

アップデート(新しいソリューション)

このアップデートは、iOS 7 のナビゲーション バーの問題に対する最適なソリューションです。ナビゲーション バーの色の例を設定できます。

注 : デフォルトのナビゲーション コントローラーを使用する場合は、古いソリューションを使用してください。

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
    {
        UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
        FakeNavBar.backgroundColor = [UIColor whiteColor];

        float navBarHeight = 20.0;
        for (UIView *subView in self.window.subviews) {

            if ([subView isKindOfClass:[UIScrollView class]]) {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
            } else {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
            }
        }
        [self.window addSubview:FakeNavBar];
    }

    return YES;

}

古い解決策 - 以前のコードを使用する場合は、次のコードと画像を無視してください

これは iOS 7 ナビゲーション バー ソリューションの古いバージョンです。

次のコードで問題を解決しました。これはステータスバーを追加するためのものです。didFinishLaunchingWithOptions

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    UIView *addStatusBar = [[UIView alloc] init];
    addStatusBar.frame = CGRectMake(0, 0, 320, 20);
    addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
    [self.window.rootViewController.view addSubview:addStatusBar];
}

また、Interface Builderの場合、これは iOS 6 で開いたときのためのものです。0 ピクセルから始まります。

注: iOS 6/7 デルタは、詳細ペインの [ファイル インスペクター] (一番左のアイコン) でビュー コントローラーの [自動レイアウトを使用] をオフにした場合にのみ表示されます。

ここに画像の説明を入力してください

于 2013-09-23T18:35:28.413 に答える
5

私はこれをすべてのView Controllerで使用しましたが、簡単です。すべての viewDidLoad メソッドに次の行を追加します。

- (void)viewDidLoad{
    //add this 2 lines:
    if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

    [super viewDidLoad];
}
于 2013-10-22T15:40:58.877 に答える
4

この簡単な方法を試してみてください....

ステップ1:単発で変更する場合viewController

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];

Step 2 : アプリケーション全体を変更する

info.plist
      ----> Status Bar Style
                  --->UIStatusBarStyle to UIStatusBarStyleBlackOpaque

ステップ3:これもそれぞれに追加して高さviewWillAppearを調整しますstatusbariOS7

    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 7) {
        CGRect frame = [UIScreen mainScreen].bounds;
        frame.origin.y+=20.0;
        frame.size.height-= 20.0;
        self.view.frame = frame;
        [self.view layoutIfNeeded];
    }
于 2014-04-15T09:04:15.347 に答える
3

Interface Builder には、オフセットの問題を解決することを目的とした iOS 6/7 Delta プロパティを呼び出すオプションがあります。

Stack Overflow の質問Interface Builder: What are the UIView's Layout iOS 6/7 Deltas for? で確認してください。.

于 2013-09-16T08:04:10.957 に答える
3

iOS 7 で iOS 6 のようなステータスバーを実現しました。

info.plist で UIViewControllerBasedStatusBarAppearance を NO に設定します

このコードを- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptionsメソッドに貼り付けます

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    [application setStatusBarStyle:UIStatusBarStyleLightContent];
    self.window.clipsToBounds =YES;
    self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height);

    //Added on 19th Sep 2013
    NSLog(@"%f",self.window.frame.size.height);
    self.window.bounds = CGRectMake(0,0, self.window.frame.size.width, self.window.frame.size.height);
}

すべてのビューを 20 ピクセル押し下げる可能性があります。それを克服するには、-(void)viewDidAppear:(BOOL)animatedメソッドで次のコードを使用します

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    CGRect frame=self.view.frame;
    if (frame.size.height==[[NSUserDefaults standardUserDefaults] floatForKey:@"windowHeight"])
    {
        frame.size.height-=20;
    }
    self.view.frame=frame;
}

didFinishLauncing メソッドでウィンドウを割り当てた後、windowHeight Userdefaults の値を設定する必要があります。

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[NSUserDefaults standardUserDefaults] setFloat:self.window.frame.size.height forKey:@"windowHeight"];
于 2013-09-27T07:05:01.337 に答える
2

Interfaceビルダーを使用している場合は、これを試してください:

あなたのxibファイルで:

1) メイン ビューを選択し、背景色を黒 (またはステータス バーの色にしたい色) に設定します。

2) バックグラウンドが、コントローラーのビューの最上位の子として配置された自己完結型のサブビューであることを確認します。
背景を移動して、コントローラーのビューの直接の子にします。自動サイズ調整パネルをチェックして、すべてのフレーム エッジをロックし、両方の柔軟な軸を有効にしたことを確認します。これが UIImageView の場合は、コンテンツ モードを [スケールに合わせる] に設定します。プログラムでは、これは contentMode が UIViewContentModeScaleToFill に設定され、自動サイズ変更マスクが (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight) に設定されるように変換されます。

3) ロックされているすべてのものを上に移動し、20 ポイント下に移動し、iOS 6/7 デルタ Y を -20 に設定します。
自動サイズ変更パネルのトップ フレームにロックされているすべてのトップ レベルの子は、20 ポイント下に移動し、iOS 6/7 デルタ Y を -20 に設定する必要があります。(それらをすべて選択し、下向き矢印を 20 回クリックします。他に良い方法はありますか?)

4) 柔軟な高さを持っていた上記のすべてのアイテムの iOS 6/7 デルタ高さを調整します。 フレームの上部と下部にロックされ、自動サイズ変更パネルで柔軟な高さが有効になっている項目は、iOS 6/7 デルタの高さも 20 に設定する必要があります。これには、上記の背景ビューが含まれます。これは直感に反するように見えるかもしれませんが、これらが適用される順序のために必要です。最初にフレームの高さが (デバイスに基づいて) 設定され、次にデルタが適用され、最後にすべての子フレームのオフセット位置に基づいて自動サイズ調整マスクが適用されます。

5) 最後に、上部フレームではなく下部フレームにロックされた項目には、デルタはまったく必要ありません。

これにより、iOS7 と iOS6 で同じステータス バーが表示されます。

一方、iOS6 との互換性を維持しながら iOS7 のスタイリングが必要な場合は、背景ビューのデルタ Y / デルタ高さの値を 0 に設定します。

詳細な iOS7 移行情報については、投稿全体を参照してください: http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html

于 2013-09-23T00:30:31.400 に答える
2

フレームを直接操作することができなくなるため、自動レイアウトを使用する場合、これは圧倒的な問題になる可能性があります。手間をかけずに簡単な解決策があります。

最終的にユーティリティ クラスにユーティリティ メソッドを記述し、すべてのビュー コントローラのviewDidLayoutSubviewsメソッドから呼び出しました。

+ (void)addStatusBarIfiOS7:(UIViewController *)vc
    {
        if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
            CGRect viewFrame = vc.view.frame;
            if(viewFrame.origin.y == 20) {
                //If the view's y origin is already 20 then don't move it down.
                return;
            }
            viewFrame.origin.y+=20.0;
            viewFrame.size.height-= 20.0;
            vc.view.frame = viewFrame;
            [vc.view layoutIfNeeded];
        }
    }

viewDidLayoutSubviewsステータスバーが必要なView Controllerでメソッドをオーバーライドします。Autolayout の負担を乗り越えることができます。

- (void)viewDidLayoutSubviews
{
    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    [super viewDidLayoutSubviews];
    [MyUtilityClass addStatusBarIfiOS7:self];
}
于 2014-03-28T17:18:43.117 に答える
1

これを行う最も簡単な方法は、古い SDK を最新の Xcode にインストールすることです。

古いSDKを最新のXcodeにインストールするには?

  1. http://www.4shared.com/zip/NlPgsxz6/iPhoneOS61sdk.htmlから iOS 6.1 SDK を取得するか、古い Xcode をダウンロードしてそのコンテンツからSDK を取得できます。

  2. このフォルダーを解凍して /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs に貼り付けます

  3. xcode を再起動します。

  4. プロジェクトのビルド設定で古い SDK を選択できるようになりました

お役に立てば幸いです。それは私のために働いた=)

于 2013-10-03T19:06:25.263 に答える
1

presentViewController:animated:completion:めちゃくちゃなを使用しwindow.rootViewController.viewているため、この問題に対する別のアプローチを見つける必要がありました。rootViewController の UIView をサブクラス化することで、モーダルとローテーションで動作するようになりました。

.h

@interface RootView : UIView

@end

.m

@implementation RootView

-(void)setFrame:(CGRect)frame
{
    if (self.superview && self.superview != self.window)
    {
        frame = self.superview.bounds;
        frame.origin.y += 20.f;
        frame.size.height -= 20.f;
    }
    else
    {
        frame = [UIScreen mainScreen].applicationFrame;
    }

    [super setFrame:frame];
}

- (void)layoutSubviews
{
    self.frame = self.frame;

    [super layoutSubviews];
}

@end

これで、iOS7 アニメーションの強力な回避策ができました。

于 2013-10-08T16:47:14.403 に答える
1

私はこの回答に遅れていますが、私がしたことを共有したいだけです。これは基本的に最も簡単な解決策です

まず最初に->info.plistファイルに移動し、ステータスバーのスタイルを追加->透明な黒のスタイル(アルファ0.5)

さて、ここに行きます:-

このコードを AppDelegate.m に追加します

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
     //Whatever your code goes here
  if(kDeviceiPad){

     //adding status bar for IOS7 ipad
         if (IS_IOS7) {
              UIView *addStatusBar = [[UIView alloc] init];
              addStatusBar.frame = CGRectMake(0, 0, 1024, 20);
              addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //change this to match your navigation bar
              [self.window.rootViewController.view addSubview:addStatusBar];
                    }
                }
    else{

         //adding status bar for IOS7 iphone
        if (IS_IOS7) {
            UIView *addStatusBar = [[UIView alloc] init];
            addStatusBar.frame = CGRectMake(0, 0, 320, 20);
            addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //You can give your own color pattern
            [self.window.rootViewController.view addSubview:addStatusBar];
        }

    return YES;
   }
于 2014-02-26T06:39:50.667 に答える
0

これは共有するには遅すぎるかもしれませんが、私は誰かを助けるかもしれない貢献する何かを持っています.UINavigationBarをサブクラス化しようとしていて、黒いステータスバーと白いステータスバーテキストでios 6のように見せたいと思っていました.

これが私がそのために働いていることを見つけたものです

        self.navigationController?.navigationBar.clipsToBounds = true
        self.navigationController?.navigationBar.translucent = false
        self.navigationController?.navigationBar.barStyle = .Black
        self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

ステータスバーの背景を黒く、ステータスバーのテキストを白く、ナビゲーションバーの色を白くしました。

iOS 9.3、X コード 7.3.1

于 2016-05-31T11:16:30.377 に答える
0

iOS 7 でステータス バーを非表示にする手順:

1. アプリケーションの info.plist ファイルに移動します。

2.設定、コントローラーベースのステータスバーの外観の表示:ブール値NO

ステータスバーの問題が解決したことを願っています.....

于 2014-01-30T11:43:30.083 に答える
0

ステータスバーをまとめて非表示にすることができます。したがって、アプリはフルスクリーンになります。それがあなたが得る最高のものだと思います。

UIStatusBarStyleNoneまたはターゲット設定で設定します。

于 2013-08-22T16:29:41.083 に答える