Высота SwiftUI NavigationBar

Как получить текущую высоту NavigationBar? В UIKit мы могли получить

navigationController?.navigationBar.frame.height

но ничего не могу найти для SwiftUI ...


person yoprst    schedule 15.02.2020    source источник
comment
Подход может быть таким же, как и для TabBar в Программном определении высоты панели вкладок или высоты TabView в SwiftUI   -  person Asperi    schedule 15.02.2020
comment
TY, это ответ   -  person yoprst    schedule 17.02.2020


Ответы (2)


На основе этого сообщения (благодаря 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)
            }
        }
    }
}

И тогда мы можем вызвать это из любого View:

.background(NavBarAccessor { navBar in
      print(">> NavBar height: \(navBar.bounds.height)")
                // !! use as needed, in calculations, @State, etc.
 })
person yoprst    schedule 17.02.2020
comment
Это прекрасно работает. Но не используйте его в NavigationView, поскольку тогда контроллер навигации будет равен нулю. Кроме того, typealias в NavBarAccessor может быть удален. - person José; 20.10.2020

Основываясь на ответе @yoprst, вместо того, чтобы настраивать вычисления и переменные @State, вы также можете вернуть View для вставки непосредственно в иерархию:

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)
            }
        }
    }
}

Использование:

VStack {
    NavigationBarAccessor { navigationBar in
        Spacer()
            .frame(height: navigationBar.frame.height)
    }
}
person rob_the_dev    schedule 02.06.2021