web-dev-qa-db-ja.com

IOS 7でステータスバーとナビゲーションバーが私のビューの境界を越えて表示される

私は最近iOS 7で自分のアプリをテストするために Xcode 5 DPをダウンロードしました。

viewDidLayoutSubviewsでは、ビューの範囲を表示します。

{{0、0}、{320、568}}

これにより、ナビゲーションバーとステータスバーの下にコンテンツが表示されます。

メイン画面の高さを取得し、ステータスバーの高さとナビゲーションバーの高さを差し引くことで、自分で高さを計算できることはわかっていますが、これは不要な余分な作業のようです。

どうすればこの問題を解決できますか?

更新:

私はこの特定の問題に対する解決策を見つけました。ナビゲーションバーの半透明のプロパティをNOに設定します。

self.navigationController.navigationBar.translucent = NO;

これにより、ビューがナビゲーションバーとステータスバーの下に囲まれないようになります。

しかし、ナビゲーションバーを半透明にしたい場合の解決策は見つかりませんでした。たとえば、写真をフルスクリーンで表示しているときに、ナビゲーションバーを半透明にし、ビューをその下にフレームで表示したいと思います。それはうまくいきますが、ナビゲーションバーの表示/非表示を切り替えると、私はもっと奇妙な結果を経験しました。最初のサブビュー(UIScrollView)は、その境界y Originが毎回変更されます。

432
beebcon

これを達成するには、iOS7 SDKでedgesForExtendedLayoutという新しいプロパティを実装します。これを達成するために次のコードを追加してください。

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

あなたは-(void)viewDidLoadメソッドに上記を追加する必要があります。

iOS 7では、UIの外観のレイアウトとカスタマイズ方法にいくつかの変更が加えられています。ビューコントローラのレイアウト、色合い、およびフォントの変更は、アプリ内のすべてのUIKitオブジェクトに影響します。さらに、ジェスチャー認識APIの機能強化により、ジェスチャー操作に対するきめ細かい制御が可能になります。

ビューコントローラを使用する

IOS 7では、View Controllerはフルスクリーンレイアウトを使用します。同時に、iOS 7では、View Controllerによるビューのレイアウト方法をより細かく制御できます。特に、全画面レイアウトの概念は、ビューコントローラがそのビューの各Edgeのレイアウトを指定できるように改良されました。

IOS 7では、wantsFullScreenLayout View Controllerプロパティは推奨されていません。現在wantsFullScreenLayout = NOを指定している場合、View Controllerは、iOS 7で実行したときに予期しない画面位置にコンテンツを表示することがあります。

View Controllerによるビューのレイアウト方法を調整するために、UIViewControllerには次のプロパティがあります。

  • edgesForExtendedLayout

edgesForExtendedLayoutプロパティは、noneとallを指定するのに加えて、長方形の4つの辺のそれぞれを指定するUIRectEdge型を使用します。バーの半透明性に関係なく、ビューのどの辺を延長するかを指定するにはedgesForExtendedLayoutを使用します。デフォルトでは、このプロパティの値はUIRectEdgeAllです。

  • extendedLayoutIncludesOpaqueBars

デザインが不透明なバーを使用している場合は、edgesForExtendedLayoutプロパティも _ no _ に設定してextendedLayoutIncludesOpaqueBarsを調整します。 (extendedLayoutIncludesOpaqueBarsのデフォルト値は _ no _ です。)

  • automaticallyAdjustsScrollViewInsets

スクロールビューのコンテンツインセットを自動的に調整したくない場合は、automaticallyAdjustsScrollViewInsets _ no _ に設定します。 (automaticallyAdjustsScrollViewInsetsのデフォルト値は _ yes _ です。)

  • topLayoutGuide、bottomLayoutGuide

topLayoutGuideおよびbottomLayoutGuideプロパティは、View Controllerのビュー内の上下のバーの端の位置を示します。バーがビューの上部または下部と重なる場合は、Interface Builderを使用して、topLayoutGuideの下部またはbottomLayoutGuideの上部に制約を作成することによって、ビューをバーに対して相対的に配置できます。 (バーがビューと重ならないようにする場合は、topLayoutGuideの下部がビューの上部と同じになり、bottomLayoutGuideの上部がビューの下部と同じになります。)両方のプロパティは要求時に遅延作成されます。

参照してください、 アップルのdoc

494
Nandha

どれだけ遠くにシフトするかを計算する必要はありません。このための組み込みプロパティがあります。 Interface Builderで、自分のView Controllerを強調表示してから、属性インスペクタに移動します。ここでは、 "Extend Edges"という単語の横にいくつかのチェックボックスが表示されます。ご覧のとおり、最初のスクリーンショットでは、デフォルトではコンテンツが上下のバーの下に表示されますが、不透明なバーの下には表示されません。

最初のスクリーンショットを見るとわかるように、ナビゲーションバーの下に隠れている2つのUI要素があります。これらの要素、UIButtonとUISegmentedControlはどちらも "y"原点がゼロに設定され、View Controllerはトップバーより下のコンテンツを許可するように設定されています。

enter image description here

この2番目のスクリーンショットは、[Under Top Bars]チェックボックスをオフにしたときの動作を示しています。ご覧のとおり、View Controllerの表示は、そのy Originがナビゲーションバーの真下にくるように適切にシフトされています。

enter image description here

これは-[UIViewController edgesForExtendedLayout]を使用してプログラム的に達成することもできます。 edgeForExtendedLayout および UIRectEdge のクラスリファレンスへのリンクです。

[self setEdgesForExtendedLayout:UIRectEdgeNone];
110
Mick MacCallum

私はプログラム的にビューを作成しましたが、これは私のために機能することになりました。

- (void) viewDidLayoutSubviews {
    // only works for iOS 7+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;

        // snaps the view under the status bar (iOS 6 style)
        viewBounds.Origin.y = topBarOffset * -1;

        // shrink the bounds of your view to compensate for the offset
        viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
        self.view.bounds = viewBounds;
    }
}

出典 (in topLayoutGuide pg.39の下のセクション)。

33
Stunner

IOS 10以降のNIB/XIBファイルでも動作するSwift 3/Swift 4ソリューション:

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}
25
flo_23

ビューに半透明のナビゲーションバー(これは一種のNiceです)を持たせたい場合は、contentInsetなどを設定する必要があります。

これが私のやり方です。

// Check if we are running on ios7
if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7) {
      CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame];
      float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height;

      myContentView.contentInset = UIEdgeInsetsMake(heightPadding, 0.0, 0.0, 0.0);
}
10
Magnus

アプリのplistファイルに行を追加し、それを "View Controller-based Status bar appearance"と呼び、 _ no _ に設定します。

9
Idan

edgesForExtendedLayoutはiOS 7のコツです。ただし、iOS 7 SDKでアプリケーションを構築してiOS 6にデプロイすると、ナビゲーションバーは半透明に見え、その下にビューが表示されます。そのため、iOS 7とiOS 6の両方で修正するには、次のようにします。

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
9

最も簡単なトリックは、 _ nib _ ファイルを開き、次の2つの簡単な手順を実行することです。

  1. それを切り替えて、好みのものに設定してください。

Enter image description here

  1. 下に移動したいUIViewの/ UIIMageView /を選択します。私の場合はロゴだけが重なっていて、デルタを+15に設定しました。 (または手順1でiOS 7を選択した場合は-15)

Enter image description here

そして 結果

BeforeAfter

7
Riskov

迅速なソリューション

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.edgesForExtendedLayout = UIRectEdge.None
}
5
fatihyildizhan

スイフト3

override func viewWillAppear(_ animated: Bool) {
    self.edgesForExtendedLayout = []
}
4
Shahrukh

私はStunnerの答えをさらに詳しく述べ、それがiOS-7であるかどうかをチェックするためのifステートメントを追加したいと思います。なぜなら、iOS 6でそれをテストしたときに私のアプリがクラッシュするからです。

追加は追加されるでしょう:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

だから私はあなたのMyViewControler.mファイルにこのメソッドを追加することをお勧めします:

- (void) viewDidLayoutSubviews {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.Origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
    }
}
4
werdsackjon

私は広告を表示するためにAppleによって書かれたBannerViewControllerとBannerViewControllerに埋め込まれたScrollViewControllerを使うシナリオを持っています。

ナビゲーションバーが私のコンテンツを隠すのを防ぐために、私は二つの変更をしなければなりませんでした。

1)BannerViewController.mを修正します。

- (void)viewDidLoad
{
   [super viewDidLoad];
   float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
   if (systemVersion >= 7.0) {
      self.edgesForExtendedLayout = UIRectEdgeNone;
   }
}

2)ScrollViewContollerを修正する

- (void)viewDidLoad
{
    [super viewDidLoad];
    float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (systemVersion >= 7.0) {
        self.edgesForExtendedLayout = UIRectEdgeBottom;
    }
}

これで、広告はナビゲーションバーで覆われずにビューの下部に正しく表示され、上部のコンテンツは途切れません。

3
Xavier John

このようにトップレイアウトに制約を加える enter image description here

2
carmen_munich

以下のコードを設定するだけで表示されます。

  if ([[[UIDevice currentDevice] systemVersion] floatValue]<= 7) {
self.edgesForExtendedLayout = UIRectEdgeNone;
 }
2

私には、最も簡単な解決策はplistに2つのキーを追加することです

enter image description here

1
giuseppe

ドロップダウンリストから、キー "View Controllerベースのステータスバーの外観"をinfo.plistの行として追加します。このようなもの:

Enter image description here

1
Kursat Turkay

私は別のUIViewControllerを提示し、ステータスバーの下にナビゲーションバーが表示された後にiPadsによるアプリケーション(armv7、armv7s、amr64)に同じ問題を抱えていました。私はストーリーボードを使っていて、InterfaceBuilderでUIViewControllerを使ってFullScreen - > Current ContextからPresentationを設定し、この問題を解決しています。それは私のアプリでのみiPad => iOS8.0(iOS8.1でテスト)のためにそしてiOS 7.1とiPadのために働かない! see screenshot

1
Alexej W.

IOS 7のステータスバーを隠すには:

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

2.And Set、View Controllerベースのステータスバーの外観:ブールNO

私はステータスバーの問題を解決したい.....

0
chandrika

私の場合はloadView()が中断されました
このコード:self.edgesForExtendedLayout = UIRectEdgeNone

しかし、loadView()を削除した後は、すべてうまくいきました。

0
DevB2F

Swift 4.2 - Xcode 10.0 - iOS 12.0:

if #available(iOS 11.0, *) {} else {
  self.edgesForExtendedLayout = []
  self.navigationController?.view.backgroundColor = .white
}
0
juliancadi