How to get current NavigationBar height? In UIKit we could get
navigationController?.navigationBar.frame.height
but can't find anything for SwiftUI...
How to get current NavigationBar height? In UIKit we could get
navigationController?.navigationBar.frame.height
but can't find anything for SwiftUI...
Based on this post (thanks to Asperi): https://stackoverflow.com/a/59972635/12299030
struct NavBarAccessor: UIViewControllerRepresentable {
var callback: (UINavigationBar) -> Void
private let proxyController = ViewController()
func makeUIViewController(context: UIViewControllerRepresentableContext<NavBarAccessor>) ->
UIViewController {
proxyController.callback = callback
return proxyController
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavBarAccessor>) {
}
typealias UIViewControllerType = UIViewController
private class ViewController: UIViewController {
var callback: (UINavigationBar) -> Void = { _ in }
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navBar = self.navigationController {
self.callback(navBar.navigationBar)
}
}
}
}
And then we can call this from any View:
.background(NavBarAccessor { navBar in
print(">> NavBar height: \(navBar.bounds.height)")
// !! use as needed, in calculations, @State, etc.
})
Building on @yoprst 's response, rather than configure calculations and @State variables, you could also return a View
to insert directly into the hierarchy:
struct NavigationBarAccessor: UIViewControllerRepresentable {
var callback: (UINavigationBar) -> (AnyView)
private let proxyViewController = ProxyViewController()
func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationBarAccessor>) -> UIViewController {
self.proxyViewController.callback = callback
return proxyViewController
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationBarAccessor>) {
}
private class ProxyViewController: UIViewController {
var callback: ((UINavigationBar) -> AnyView)?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navigationBar = self.navigationController?.navigationBar {
_ = self.callback?(navigationBar)
}
}
}
}
Usage:
VStack {
NavigationBarAccessor { navigationBar in
Spacer()
.frame(height: navigationBar.frame.height)
}
}
Use GeometryReader, like this:
ZStack {
GeometryReader { geometry in
Rectangle().fill(Color.blue).frame(height: geometry.safeAreaInsets.bottom + 44.0)
}
Text("Content")
}
.edgesIgnoringSafeArea(.top)