更新于2018年1月7日
该代码支持XCode 9.2,iOS 11.2
我有同样的问题。下面是我的解决方案。我假设身高为66。
如果有帮助,请选择我的答案。
创建CINavgationBar.swift
   import UIKit
@IBDesignable
class CINavigationBar: UINavigationBar {
    
    @IBInspectable var customHeight : CGFloat = 66
    override func sizeThatFits(_ size: CGSize) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        print("It called")
        self.tintColor = .black
        self.backgroundColor = .red
        for subview in self.subviews {
            var stringFromClass = NSStringFromClass(subview.classForCoder)
            if stringFromClass.contains("UIBarBackground") {
                subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)
                subview.backgroundColor = .green
                subview.sizeToFit()
            }
            stringFromClass = NSStringFromClass(subview.classForCoder)
            
            if stringFromClass.contains("UINavigationBarContentView") {
                
                let centerY = (customHeight - subview.frame.height) / 2.0
                subview.frame = CGRect(x: 0, y: centerY, width: self.frame.width, height: subview.frame.height)
                subview.backgroundColor = .yellow
                subview.sizeToFit()
            }
        }
    }
}
设置情节提要


设置自定义NavigationBar类


添加TestView +设置SafeArea
ViewController.swift
import UIKit
class ViewController: UIViewController {
    var navbar : UINavigationBar!
    @IBOutlet weak var testView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationController?.navigationBar.sizeToFit()
        print("NavigationBar Frame : \(String(describing: self.navigationController!.navigationBar.frame))")
    }
    
    override var prefersStatusBarHidden: Bool {
        return true
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(false)
        
        if #available(iOS 11.0, *) {
            
            self.additionalSafeAreaInsets.top = 22
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
}
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        var backButton: UIBarButtonItem!
        let backImage = imageFromText("Back", font: UIFont.systemFont(ofSize: 16), maxWidth: 1000, color:UIColor.white)
        backButton = UIBarButtonItem(image: backImage, style: UIBarButtonItemStyle.plain, target: self, action: #selector(SecondViewController.back(_:)))
        self.navigationItem.leftBarButtonItem = backButton
        self.navigationItem.leftBarButtonItem?.setBackgroundVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
    }
    override var prefersStatusBarHidden: Bool {
        return true
    }
    @objc func back(_ sender: UITabBarItem){
        self.navigationController?.popViewController(animated: true)
    }
    
    func sizeOfAttributeString(_ str: NSAttributedString, maxWidth: CGFloat) -> CGSize {
        let size = str.boundingRect(with: CGSize(width: maxWidth, height: 1000), options:(NSStringDrawingOptions.usesLineFragmentOrigin), context:nil).size
        return size
    }
    
    func imageFromText(_ text:NSString, font:UIFont, maxWidth:CGFloat, color:UIColor) -> UIImage
    {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineBreakMode = NSLineBreakMode.byWordWrapping
        paragraph.alignment = .center 
        let attributedString = NSAttributedString(string: text as String, attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.paragraphStyle:paragraph])
        let size = sizeOfAttributeString(attributedString, maxWidth: maxWidth)
        UIGraphicsBeginImageContextWithOptions(size, false , 0.0)
        attributedString.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
}
 

黄色是barbackgroundView。黑色不透明度为BarContentView。
然后我删除了BarContentView的backgroundColor。

而已。