How to get current NavigationBar height? In UIKit we could get
navigationController?.navigationBar.frame.height
but can't find anything for SwiftUI...
height; const navbarHeight = screenHeight – windowHeight + StatusBar.
To change a navigation bar color in SwiftUI, you apply toolbarBackground modifier to the content view of NavigationStack . NavigationView is deprecated in iOS 16. toolbarBackground accepts two parameters. ShapeStyle : The style to display as the background of the bar.
On iPhone tab bars remain 49 points tall in portrait and 32 points tall in landscape. iPhone X added extra height for the Home Bar to toolbars and tab bars and their sizes are unchanged from iOS 11: 83 points tall in portrait and 53 points tall in landscape.
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)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With