【问题标题】:Hide UINavigationController's navigationBar when the root controller is a UIHostingController当根控制器是 UIHostingController 时隐藏 UINavigationController 的 navigationBar
【发布时间】:2020-12-01 15:50:06
【问题描述】:

我正在努力隐藏 navigationBar,如果根控制器不是 SwiftUI UIHostingController,它将被正确隐藏。

我尝试了以下方法:

  • 在创建后设置navigationController.isNavigationBarHidden = true,在viewDidLoadviewWillAppear

  • UIHostingControllerrootView 添加.navigationBarHidden(true).navigationBarBackButtonHidden(true)

这可能是 Apple 的错误吗?我正在使用 Xcode 11.6。

我所有的尝试:

class LoginController: UINavigationController, ObservableObject
{
    static var newAccount: LoginController
    {
        let controller = LoginController()
        let view = LoginViewStep1()
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(true)
        controller.viewControllers = [UIHostingController(rootView: view)]
        controller.isNavigationBarHidden = true
        return controller
    }
    
    override func viewWillAppear(_ animated: Bool)
    {
        super.viewWillAppear(animated)
        
        self.isNavigationBarHidden = true
    }

    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.isNavigationBarHidden = true
    }
}

struct LoginViewStep1: View
{
    // ...
    
    var body: some View
    {
        VStack {
            // ...
        }
        .navigationBarHidden(true)
        .navigationBarBackButtonHidden(true)
    }
}

【问题讨论】:

  • 你会展示你的代码吗?
  • 添加了我的代码@Asperi。

标签: ios uinavigationcontroller swiftui uinavigationbar uihostingcontroller


【解决方案1】:

这里有一个解决方案。使用 Xcode 11.4 / iOS 13.4 测试

修改了你的代码:

class LoginController: UINavigationController, ObservableObject
{
    static var newAccount: LoginController
    {
        let controller = LoginController()
        let view = LoginViewStep1()
        controller.viewControllers = [UIHostingController(rootView: view)]

        // make it delayed, so view hierarchy become constructed !!!
        DispatchQueue.main.async {
            controller.isNavigationBarHidden = true
        }

        return controller
    }
}

struct LoginViewStep1: View
{
    var body: some View
    {
        VStack {
            Text("Hello World!")
        }
    }
}

SceneDelegate中的测试部分

if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)

    window.rootViewController = LoginController.newAccount

    self.window = window
    window.makeKeyAndVisible()
}

【讨论】:

  • 成功了!谢谢。有人会认为viewDidLoadviewWillAppear 已经足够“延迟”了。
  • 似乎推第二个UIHostingController 需要类似的破解。
【解决方案2】:

替代解决方案是使用 UINavigationControllerDelegate:

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
    // Required because pushing UIHostingController makes the navigationBar appear again
    isNavigationBarHidden = true
}

使用 iOS 14.5 - Xcode 12.5 测试

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    相关资源
    最近更新 更多