Your custom bar's view is being laid out like:
[nav.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor];
Anything that is constrained to the view.safeAreaLayoutGuide.topAnchor will be below the statusBar + navigationBar because that is the safe area.. If it is constrained to safeAreaLayoutGuide.bottomAnchor, then it will be above all tabBars or bottom bars so that iPhone X users can swipe up without touching your view..
However, anything constrained to view.topAnchor will be constrained to the top of the view (IE: The screen)..
So constrain your custom view to the top of your controller's view. Then in viewDidLayoutSubviews
, add safeAreaInsets.top
to the height. This will allow your view to be touching the top of the screen, but tall/large enough to extend below the navBar. Your will need to adjust the contents of your view to layout further down by the same inset top.
//
// ViewController.swift
// SONav
//
// Created by Brandon Anthony on 2017-11-17.
// Copyright © 2017 SO. All rights reserved.
//
import UIKit
class CustomNav : UINavigationBar {
var desiredHeight: CGFloat = 88.0
override init(frame: CGRect) {
super.init(frame: frame)
desiredHeight = frame.size.height
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
var size = super.sizeThatFits(size)
size.height = desiredHeight
return size
}
override var frame: CGRect {
get {
return super.frame
}
set {
var frm = newValue
frm.size.height = desiredHeight
super.frame = frm
}
}
override func layoutSubviews() {
super.layoutSubviews()
for subview in self.subviews {
if NSStringFromClass(type(of: subview)).contains("Background") {
subview.frame.size.height = 0
}
else if NSStringFromClass(type(of: subview)).contains("ContentView") {
subview.frame.origin.y = 0
}
}
}
}
class CustomNavigationController : UINavigationController {
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)
self.setNeedsStatusBarAppearanceUpdate()
}
}
class ViewController: UIViewController {
var customNav: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//Navigation Bar Setup
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = UIColor.clear
self.navigationController?.navigationBar.backgroundColor = UIColor.clear
self.navigationController?.navigationBar.shadowImage = nil
self.view.backgroundColor = UIColor.white
self.customNav = CustomNav(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 100))
self.customNav.backgroundColor = UIColor.blue
self.view.addSubview(self.customNav!)
NSLayoutConstraint.activate([
self.customNav.leftAnchor.constraint(equalTo: self.view.leftAnchor),
self.customNav.rightAnchor.constraint(equalTo: self.view.rightAnchor),
self.customNav.topAnchor.constraint(equalTo: self.view.topAnchor),
self.customNav.heightAnchor.constraint(equalToConstant: 100.0)
])
self.customNav.translatesAutoresizingMaskIntoConstraints = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}