So I've spent a huge amount of time researching this, and I've found the answer, but beware: it's very, very hacky.
So, the view that's responsible for creating this gray glow on the navigation bar is something called _UIVisualEffectBackdropView. More specifically, this view's layer has four filters attached (all of them are private CAFilters), and first of them, named luminanceCurveMap, creates this gray color for the navigation bar. So my solution is to
- Find
_UIVisualEffectBackdropView in the view hierarchy of UINavigationBar
- Remove
luminanceCurveMap filter of of its layer.
Here's the function I created to find _UIVisualEffectBackdropView in the hierarchy:
extension UIView {
fileprivate static func findRecursively(typeName: String, in view: UIView) -> UIView? {
let typeOf = type(of: view)
if String(describing: typeOf) == typeName {
return view
} else {
for subview in view.subviews {
if let found = UIView.findRecursively(typeName: typeName, in: subview) {
return found
}
}
return nil
}
}
}
And then override viewDidAppear in your custom UINavigationController subclass (only viewDidAppear, viewWillAppear for example didn't work):
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let backdrop = UIView.findRecursively(typeName: "_UIVisualEffectBackdropView", in: navigationBar) {
let luminanceCurveMapIndex = backdrop.layer.filters?.firstIndex { filter in
if let caFilter = filter as? NSObject, let name = caFilter.value(forKey: "name") as? String {
return name == "luminanceCurveMap"
} else {
return false
}
}
if let index = luminanceCurveMapIndex {
backdrop.layer.filters?.remove(at: index)
}
}
}
I know it's a lot, but that's the I came out with. It preserves all native translucency behavior while giving me the look I needed.