web-dev-qa-db-ja.com

iOS 11カスタムナビゲーションバーがステータスバーの下に表示される

xcode 9をダウンロードしたところ、この奇妙な問題が発生しています。iOS11では、カスタムnavbarのサイズが半分になり、ステータスバーの下に表示されます。iOS10では正常に動作します。

ここに私のコードがあります

let newNavbar: UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 64))
let navItem = UINavigationItem()

//create and assign the items

newNavbar.setItems([navItem], animated: false)
view.addSubview(newNavbar)

左側にios11、右側にios10のスクリーンショットがあります。

enter image description here

13
iknowNothing

あなたのコードは常に間違っていました。手動で追加したナビゲーションバーの高さを自分で設定したり、ビューの上部に配置したりしないでください。 UIBarPositioningDelegateメカニズムを使用してその位置を.topAttachedに設定できるように、ナビゲーションバーの上部をステータスバーの下部(セーフエリアの上部など)に固定し、デリゲートを与える必要があります。画面の上部まで正しく伸びます。

(ただし、自問自答する必要がありますwhyナビゲーションバーを手動で追加しています。通常、実際の操作を行わない場合でも、View ControllerをUINavigationControllerでラップしない理由はありません。ナビゲーション—すべての自動管理機能を備えたナビゲーションバーを取得するためだけです。)

23
matt

ios 11カスタムnavbarがステータスバーの下に表示される / ios 11ナビゲーションバーがステータスバーに重なる を参照してください

これが同じ問題であるかどうかはわかりませんが、iOS 11にアップグレードするときにもこれに遭遇しました。

ios 11のカスタムnavbarはステータスバーの下に表示されます を参照してください

ナビゲーションバーの高さを手動で64に設定し、スーパービューエッジに固定しました。 UINavigationBarDelegateプロトコルに準拠し、UIBarPositioningDelegateデリゲートメソッドを実装することで解決しました。

交換しました

navigationBar.autoPinEdgesToSuperviewEdgesExcludingEdge(.bottom)
navigationBar.autoSetDimension(.height, toSize: 64)

...
  if #available(iOS 11.0, *) {
    navigationBar.topAnchor.constraint(
      equalTo: self.view.safeAreaLayoutGuide.topAnchor
    ).isActive = true
  } else {
    navigationBar.topAnchor.constraint(
      equalTo: topLayoutGuide.bottomAnchor
    ).isActive = true
  }
  navigationBar.autoPinEdge(toSuperviewEdge: .left)
  navigationBar.autoPinEdge(toSuperviewEdge: .right)
  navigationBar.delegate = self
...

public func position(for bar: UIBarPositioning) -> UIBarPosition
  return .topAttached
}

これは、一部の自動レイアウト呼び出しにpurelayout DSLを使用しています( https://github.com/PureLayout/PureLayout

回答は https://stackoverflow.com/users/341994/matt にあります

5
Darren Cheng

ビューにナビゲーションバーを追加した後、自動レイアウト制約を追加してみてください

if #available(iOS 11.0, *) {
    newNavbar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    newNavbar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    newNavbar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    newNavbar.heightAnchor.constraint(equalToConstant: 64).isActive = true
}

実際には、以前のバージョンのiOSで3番目の制約を除くすべてを使用できますが、以前のバージョンですべて機能する場合は、それを台無しにしたくないかもしれません。

安全なレイアウト領域を使用すると、ナビゲーションバーがステータスバーの下に保持されます。

3
theMikeSwan

まず、ストーリーボードでNavigation Controllerの「Show Navigation Bar」がオフになっていることを確認します。

次に、「オブジェクトライブラリ」からナビゲーションバーをドラッグアンドドロップします。 Top制約を20に設定します。

「iPhone Xシミュレーター」でも完璧に機能します。

ハッピーコーディング!

1
MyApp

Swift 4.1でこのソリューションを試しました

let menuBar: UIView = {
let mb = UIView()
mb.backgroundColor = .red
mb.translatesAutoresizingMaskIntoConstraints = false
return mb
}()



private func setupMenuBar(){

view.addSubview(menuBar)

let constraints = [ menuBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                    menuBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                    menuBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                    menuBar.heightAnchor.constraint(equalToConstant: 50)]
NSLayoutConstraint.activate(constraints)
}
1
MJ Montes