web-dev-qa-db-ja.com

iOS 7:UITableViewがステータスバーの下に表示される

私のアプリケーションの最初の画面はナビゲーションバーのないUITableViewControllerです。これはコンテンツがステータスバーの下を流れるのでテキストの衝突が多いことを意味します。私はUnder top barsAdjust scroll view insetsの両方のプロパティを調整しました。これらは実際には下にスクロールしないようにしますが、テーブルビューの上部を下にしておくという犠牲を払っています。 UITableViewフレームを20ピクセルオフセットするように設定しようとしましたが、効果があるようには見えません。現在iOS 6と互換性があるアプリが必要なので、自動レイアウトを強制するためにiOS 7ストーリーボードにジャンプすることはできません。トップハイトガイドを使用してください。両方のバージョンで機能するソリューションを誰かが見つけましたか?

試したこと:edgesForExtendedLayoutを設定し、Storyboard内でUnder top barsAdjust scroll viewの設定を変更し、フレームを新しい領域に強制します。

絵は千語の価値があります。 Status bar flow under

216
Nicholas Smith

これを複製することに興味がある人のために、単にこれらのステップに従ってください:

  1. 新しいiOSプロジェクトを作成する
  2. メインストーリーボードを開き、デフォルト/初期のUIViewControllerを削除します
  3. オブジェクトライブラリから新しいUITableViewControllerをドラッグアウトします。
  4. 初期View Controllerとして設定
  5. テーブルにいくつかのテストデータを入力する

上記の手順に従うと、アプリを実行したときに、Xcodeのチェックボックスを "上、下、不透明、小節の下に延長"に微調整しても、最初の行がステータスバーの下に表示されなくなります。また、プログラムでこれに対処することはできません。

例えば。上記のシナリオでは、次のようになりますnoの効果があります。

// These do not work
self.edgesForExtendedLayout=UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;

この問題は非常にイライラさせることができます、そしてそれは、特にそれがオブジェクトライブラリからの彼ら自身の事前に配線されたUITableViewControllerに現れるので、それはAppleの終わりのバグであると思います。

私はこれを「マジックナンバー」の形式で解決しようとしている人たち全員に同意しません。 msgstr "20pxのデルタを使う"#:。このような密結合プログラミングは、Appleが私たちにここでやってほしいものではないことは間違いありません。

この問題に対する2つの解決策を発見しました。

  • UITableViewControllerのシーンを保存する
    手動で別のビューに配置せずにUITableViewControllerをストーリーボードに残したい場合は、UITableViewControllerUINavigationControllerに埋め込み(Editor> Embed In> Navigation Controller)、[Show Navigation Bar]をオフにします。検査官これは余分な調整を必要とせずに問題を解決し、ストーリーボード内のUITableViewControllerのシーンも維持します。

  • AutoLayoutを使用してUITableViewを別のビューに埋め込む(これがAppleのやり方であると私は思っています)
    空のUIViewControllerを作成し、その中にUITableViewをドラッグします。次に、Ctrlキーを押しながらUITableViewからステータスバーに向かってドラッグします。マウスがステータスバーの一番下に来ると、 "Top Layout Guide"という自動レイアウトの吹き出しが表示されます。マウスを放して、 "Vertical Spacing"を選択します。これはレイアウトシステムにステータスバーの真下に配置するように伝えます。

私は空のアプリケーションで両方の方法をテストしました、そして両方ともうまくいきます。あなたはそれらがあなたのプロジェクトのために働くようにするためにいくつかの追加の微調整をする必要があるかもしれません。

364
marinosb

あなたがプログラムで物事をやっていて、UITableViewControllerなしでUINavigationControllerを使っているなら、あなたの最善の策はviewDidLoadで以下をすることです:

スイフト3

self.tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)

以前のスウィフト

self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f);

UITableViewControllerはまだステータスバーの後ろをスクロールしますが、一番上までスクロールしても下には表示されません。

84
lipka

注意してください:これは私にとって次の設定でうまくいきました:

  • 画面上部にナビゲーションバーがありません(テーブルビューとステータスバーが一致)
  • テーブルビューはスクロール不可

上記の2つの要件が満たされていない場合、あなたのミラージュは異なるかもしれません。

元の投稿

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

- (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;
    }
}

出典 (p.37の下部のtopLayoutGuideセクションにあります)。

23
Stunner

トップの答えに追加:

2番目の方法が最初はうまくいかなかったように見えた後、私は追加のいじくり回しをし、解決策を見つけました。

TLDR。トップアンサーの2番目の解決策はほとんどうまくいくが、xCode ctrl +のいくつかのバージョンでは "Top Layout Guide"にドラッグしてVertical Spacingを選択しても何もしない。ただし、最初にTable Viewのサイズを調整してから、[Top Layout to Topレイアウトガイド]を選択すると機能します


  1. 空のViewControllerをストーリーボードにドラッグします。 View Controller

  2. UITableViewオブジェクトをビューにドラッグします。 (UITableViewControllerではありません)。青いレイアウトガイドを使用して、中央に配置します。

Table ViewCenter Image

  1. UITableViewCellをTableViewにドラッグします。これがプロトタイプの再利用セルになるので、[属性]タブで[再利用識別子]を設定するのを忘れないでください。クラッシュすることがあります。

Add Table View CellReuse Identifier

  1. UIViewControllerのカスタムサブクラスを作成し、<UITableViewDataSource, UITableViewDelegate>プロトコルを追加します。 Identity InspectorでストーリーボードのViewControllerをこのクラスに設定することを忘れないでください。

  2. 実装ファイルにTableViewのアウトレットを作成し、 "tableView"という名前を付けます。

Create OutlettableView

  1. TableViewを右クリックして、dataSourceとデリゲートの両方をViewControllerにドラッグします。

dataSource delegate

それではステータスバーにはめ込まないようにしましょう。

  1. テーブルビューの一番上の端をつかみ、一番上の近くにある破線の自動レイアウトガイドの1つに移動します

resize

  1. これで、テーブルビューから上部へのドラッグを制御し、上部スペースから上部レイアウトガイドを選択できます。

Top Space to Top Layout Guide

  1. それはあなたにTableViewのあいまいなレイアウトについてのエラーを与えるでしょう、ちょうど足りない足し算を追加してあなたのすること。

Add Missing Constraints

これでテーブルビューを通常通りに設定でき、ステータスバーが切り取られることはありません。

20
ErikAGriffin
- (void) viewDidLayoutSubviews {
    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
        self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
        if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
            self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.Origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
        self.navigationController.navigationBar.translucent = NO;
    }
}

https://developer.Apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/SupportingEarlieriOS.html#//Apple_ref/doc/uid/TP40013174-CH14-SW1

11
Olzh

これは「Swift」で書く方法です。@ lipkaの答えの調整:

tableView.contentInset = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
8
uplearnedu.com

ストーリーボードの[UIViewController]を選択し、[トップバーの下のエッジを延長]オプションをオフにします。私のために働きました。 :)

7
pegpeg

Xcode 7では、ナビゲーションバーの「半透明」のチェックマークを外すとうまくいきました。

enter image description here

5
David T

これはUITableViewControllerのためにそれを修正します(マジックナンバーなしで)。私がそれを直すことができなかった唯一の事はあなたが電話をかけているかどうかである、その場合tableViewの一番上があまりにも多く押されている。誰もがそれを解決する方法を知っているなら、私たちに知らせてください。

class MyTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()    
        configureTableViewTop()
    }

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
        coordinator.animateAlongsideTransition({ (context) -> Void in
            }, completion: { (context) -> Void in
                self.configureTableViewTop()
        })
    }

    func configureTableViewTop() { 
        tableView.contentInset.top = UIApplication.sharedApplication().statusBarFrame.height
    }
}
3
Harris

chappjcの答えは、XIBを扱うときにうまくいきます。

TableViewControllersをプログラムで作成するときの最も明確な解決策は、UITableViewControllerインスタンスを別のUIViewControllerにラップし、それに従って制約を設定することです。

ここにあります:

UIViewController *containerLeftViewController = [[UIViewController alloc] init];
UITableViewController *tableViewController = [[UITableViewController alloc] init];

containerLeftViewController.view.backgroundColor = [UIColor redColor];

hostsAndMoreTableViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[containerLeftViewController.view addSubview:tableViewController.view];

[containerLeftViewController addChildViewController:tableViewController];
[tableViewController didMoveToParentViewController:containerLeftViewController];

NSDictionary * viewsDict = @{ @"tableView": tableViewController.view ,
                              @"topGuide": containerLeftViewController.topLayoutGuide,
                              @"bottomGuide": containerLeftViewController.bottomLayoutGuide,
                              };
[containerLeftViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|"
                                                                                         options:0
                                                                                         metrics:nil
                                                                                           views:viewsDict]];
[containerLeftViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide][tableView][bottomGuide]"
                                                                                         options:0
                                                                                         metrics:nil
                                                                                           views:viewsDict]];

乾杯、ベン

2
tubtub

Kosherがどのようなものかはわかりませんが、このスキームではViewControllerのビューが下に移動し、ステータスバーの背景が白くなります。

- (void)viewDidLoad {
    [super viewDidLoad];

    // Shove everything down if iOS 7 or later
    float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (systemVersion >= 7.0f) {

        // Move the view down 20 pixels
        CGRect bounds = self.view.bounds;
        bounds.Origin.y -= 20.0;
        [self.view setBounds:bounds];

        // Create a solid color background for the status bar
        CGRect statusFrame = CGRectMake(0.0, -20.0, bounds.size.width, 20);
        UIView* statusBar = [[UIView alloc] initWithFrame:statusFrame];
        statusBar.backgroundColor = [UIColor redColor];
        [self.view addSubview:statusBar];
    }

もちろん、redColorを背景の色に変えてください。

ステータスバーの文字/記号の色を設定するには、いずれかのスウィズルを個別に行う必要があります。グローバルにこれを行うには、plistでView controller-based status bar appearance = NOStatus bar style = Opaque black styleを使います。

うまくいっているようです、そして私はそれに関するどんなバグや問題についても耳にしたいです。

2
Hot Licks

私は網膜/非網膜ディスプレイのためにこれをしました。

BOOL isRetina = FALSE;

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    if ([[UIScreen mainScreen] scale] == 2.0) {
        isRetina = TRUE;
    } else {
        isRetina = FALSE;
    }
}

if (isRetina) {
    self.edgesForExtendedLayout=UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars=NO;
    self.automaticallyAdjustsScrollViewInsets=NO;
}
1
Salim

自分のUITableViewControllerUIViewControllerに埋め込まない方がよい私のような人のために、これを試してください:

カスタムUITableViewControllerサブクラスは、tableViewのスーパービューにマスクビューを追加することができます。 viewDidAppearにマスクを追加し、viewWillDisappearからマスクを削除します。

private var statusBarMaskView: UIView!

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if let superview = self.tableView.superview {
        self.statusBarMaskView = UIView(frame: CGRect.zero)
        superview.insertSubview(self.statusBarMaskView, aboveSubview: self.tableView)
        self.statusBarMaskView.backgroundColor = self.tableView.backgroundColor

        // using a Nice constraint layout library to set the frame
        self.statusBarMaskView.pinTop(to: superview)
        self.statusBarMaskView.pinLeft(to: superview)
        self.statusBarMaskView.pinRight(to: superview)
        self.statusBarMaskView.addHeightConstraint(with: 22.0)
        ////
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    self.statusBarMaskView.removeFromSuperview()
    self.statusBarMaskView = nil
}
1
Lee Irvine

UITableViewControllerを使用する方法は、以前に行った方法とは少し異なる場合があります。それは私のために働いていますが、あなたはそれのファンではないかもしれません。私がやったことは私のUItableViewControllerを指すコンテナビューを持つView Controllerを持つことです。このようにして私はストーリーボードで提供されているTopLayoutGuideを使用することができます。コンテナービューに制約を追加するだけで、iOS7とiOS6の両方に注意を払う必要があります。

1
Phong Le

次の解決策は、マジック定数を使用せずにコード内で十分に機能し、サイズクラスを変更するユーザーを考慮に入れます。 ipad上での回転やサイドバイサイドのアプリを通して:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    // Fix up content offset to ensure the tableview isn't underlapping the status bar.
    self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0.0, 0.0, 0.0);
}
1
qix

TableViewの後に追加され、ステータスバーの下に配置された、希望の背景を持つ追加のビューを1つ使用しました。

    self.CoverView = [[UIView alloc]init];

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

    self.CoverView.frame = CGRectMake(0,0,self.view.bounds.size.width,20);
    }

    self.CoverView.backgroundColor = [UIColor whiteColor];
    self.TableView = [[UITableView alloc]initWithFrame:CGRectMake(0,
    self.CoverView.bounds.size.height,XXX, YYY)];
    [self.view addSubview:self.TableView];
    [self.view addSubview:self.CoverView];

それほどきれいではありませんが、xibなしのビュー、そしてIOS6とIOS7の両方で作業する必要がある場合は、どちらかと言えば簡単な解決策です。

1
lilislilit

Swift 3で動作 - viewDidLoad()で。

let statusBarHeight = UIApplication.shared.statusBarFrame.height

let insets = UIEdgeInsets(top: statusBarHeight, left: 0, bottom: 0, right: 0)
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets

このコードは以下のとおりです。1.ステータスバーの高さを取得します。 3.スクロールインジケーターに同じインセットを付けて、ステータスバーの下に表示します。

1
Wesh RaphLola

Abrahamchezの解決法 https://developer.Apple.com/library/ios/qa/qa1797/_index.html は次のように働きました。私は最初のビューとして単一のUITableviewcontrollerを持っていました。オフセットコードを試してnavconに埋め込むことを試みましたが、ステータスバーの透明度も解決しませんでした。

Viewcontrollerを追加して、それを初期ビューにします。これにより、重要な上下レイアウトガイドが表示されます。

古いTableviewを新しいコントローラのViewにドラッグします。

テーブルを新しいコントローラに追加するためのすべての作業を行います。

古いview controller.hファイルを、UITableViewControllerではなくUIViewControllerから継承/サブクラス化するように変更します。

UITableViewDataSourceとUITableViewDelegateをビューコントローラの.hに追加します。

検索バーなど、ストーリーボードに必要なものをすべて再接続します。

大きなことは、Apple Q&Aのように、制約を設定することです。ツールバーを挿入する手間が省けました。正確な順序はわかりません。しかし、おそらく私が作ったときに、赤いアイコンがレイアウトガイドに現れました。それをクリックして、Xcodeに制約をインストール/クリーンアップさせます。

それから私はVertical Spaceコンストレインが見つかるまで至る所でクリックし、トップの値を-20から0に変更しました、そしてそれは完全に働きました。

0
Jack Bellis

私はios 11でこの問題に直面していましたが、レイアウトはios 8 - 10.3.3には正しいものでした。私の場合は、垂直方向のスペースの制限をSuperview.TopではなくSuperview.Top Marginに設定します。これはios 8 - 11で動作します。

enter image description here

0
DareDevil

私は私のUITableViewの一番上にUISearchBarを持っていました、そして、以下はうまくいった。

self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
self.tableView.contentOffset = CGPointMake(0, -20);

共有して楽しむ...

0
Sam T
override func viewDidLoad() {
 // your code

 if let nc = self.navigationController {
   yourView.frame.Origin.y = nc.navigationBar.frame.Origin.y + nc.navigationBar.frame.height
  }
}
0
wajih

サイズをフリーフォームに設定することでうまくいきました

enter image description here

0
fengd

これはSwift 2.3です。 (Xcode 8.0)ソリューション。 UITableViewのサブクラスを作成しました。

class MYCustomTableView: UITableView
{   
    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
        contentInset    = UIEdgeInsetsZero
    }
}

コンテンツのインセットは常にゼロにする必要があります(デフォルト)。手動でゼロに設定しています。また、チェックを行うチェックメソッドを追加することもできます。チェックメソッドを正しいものにしたいだけのものではない場合もあります。変更は、テーブルビューが描画されたときにのみ反映されます(これは頻繁には起こりません)。

IBのTableViewを更新することを忘れないでください(TableViewControllerまたはViewController内のTableViewのみ)。

0
Darkwonder

私はnavigationcontrollerとtableviewcontrollerとUISplitViewControllerを使っています。これは私がマスタービューで多くの解決策を試した後にうまくいきました:

float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0f) {

    // Move the view down 20 pixels
    CGRect bounds = self.view.bounds;
    bounds.Origin.y -= 20.0;
    [self.navigationController.view setBounds:bounds];

    // Create a solid color background for the status bar
    CGRect statusFrame = CGRectMake(0.0, -20.0, bounds.size.width, 20);
    UIView* statusBar = [[UIView alloc] initWithFrame:statusFrame];
    statusBar.backgroundColor = [UIColor whiteColor];
    [statusBar setAlpha:1.0f];
    [statusBar setOpaque:YES];
    [self.navigationController.view addSubview:statusBar];
}

これはHot Licksのソリューションに似ていますが、サブビューをnavigationControllerに適用します。

0
sfr14