导航栏未显示在 childViewController 内

Posted

技术标签:

【中文标题】导航栏未显示在 childViewController 内【英文标题】:Navigation bar not displaying inside childViewController 【发布时间】:2018-04-19 10:11:09 【问题描述】:

我在我的 ios 应用中创建了一个hamburger menu

我的rootViewController 中有一个navigationBar,但现在我需要将navigationBar 移动到我的childViewController 之一,以便某些functions/buttons 工作。

现在我已将其移至childViewControllernavigationBar 不会显示。如果我使childViewController rootController navigationBar 显示正常,这是因为在我的appDelegate 中我将rootController 作为navigationController

只有当我将其设为childViewController 时,navigationBar 才会决定不显示。不知道我需要做什么才能让它工作。

这是我的appDelegate,我正在这里制作rootViewController

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.makeKeyAndVisible()
        window?.rootViewController = UINavigationController(rootViewController: jobListController())


        return true
    

这是我的汉堡菜单viewDidLoad(rootViewController),我在其中添加childViewControllers

override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = UIColor.white

        // ADD VIEWCONTROLLERS TO MENU
        view.addSubview(sideBarUIView)

        addChildViewController(sideBar)
        view.addSubview(sideBar.view)
        sideBar.view.center = sideBarUIView.center

        addChildViewController(jobList)
        view.addSubview(jobList.view)
        jobList.view.center = overlayView.center

        // ADD UI VIEWS TO HAMBURGER MENU
        view.addSubview(overlayView)
        overlayView.isHidden = true
    

这是我想将navigationBar 添加到的childViewController

class jobListController: UIViewController 
        super.viewDidLoad()

        navigationController?.navigationBar.barTintColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
        navigationController?.view.backgroundColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
        navigationController?.navigationBar.shadowImage = UIImage()

        navigationItem.title = "JOBS"

        let searchButton = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(HandleSearch))
        let addNewJobButton = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(HandleNewJob))
        searchButton.tintColor = UIColor(red:0.63, green:0.63, blue:0.63, alpha:1.0)
        addNewJobButton.tintColor = UIColor(red:0.63, green:0.63, blue:0.63, alpha:1.0)

        navigationItem.rightBarButtonItems = [addNewJobButton, searchButton]
    
  

编辑:

使用 Lukáš Mareda 的回答似乎解决了我遇到的问题后,它产生了一个新问题。

在我的 rootController(汉堡菜单)上,我可以向右滑动屏幕上的任意位置,它会打开汉堡菜单,这很棒,因为这是想要的效果。

我的 hamburgerMenu 中的一个子 viewController 有一个 tableView。如果我单击其中一个单元格并转到一个新的 viewController,仍然可以通过向右滑动访问汉堡菜单。

我只希望能够访问顶层的汉堡菜单,但我现在似乎可以在我的应用程序的任何位置访问它。

【问题讨论】:

【参考方案1】:

1) 汉堡菜单视图控制器应该是 UIViewController 的子类。 appDelegate 的第一步:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = HamburgerViewController()
        window?.makeKeyAndVisible()

        return true
    

2) HamburgerView 控制器应该将 NavigationController(或其子类)与一些 rootview 控制器嵌入。所以在 HamburgerViewController 中

override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = UIColor.white

        // ADD VIEWCONTROLLERS TO MENU
        view.addSubview(sideBarUIView)

        addChildViewController(sideBar)
        view.addSubview(sideBar.view)
        sideBar.view.center = sideBarUIView.center

        let navigationController = UINavigationController(rootViewController: jobListController())
        addChildViewController(navigationController)
        view.addSubview(navigationController.view)
        navigationController.view.center = overlayView.center

        // ADD UI VIEWS TO HAMBURGER MENU
        view.addSubview(overlayView)
        overlayView.isHidden = true
    

3) JobList 可以保持原样。我假设在当前状态下,navigationController 属性为零

更新答案

处理你的hamburgerGestureRecognizer有两个想法

1) 您可以将 hamburgerGestureRecognizer 添加到rootViewController.view 在您的情况下,它是 JobList,所以手势识别器将仅在 rootViewController 中

            let jobList = jobListController()
            let navigationController = UINavigationController(rootViewController: jobList)
            addChildViewController(navigationController)
            view.addSubview(navigationController.view)
            joblist.view.addGestureRecognizer(hamburgerGestureRecognizer)
            navigationController.view.center = overlayView.center

在 hamburgerMenu 的屏幕之间切换的地方,你可以重复使用这个识别器

viewControllerToPresent.view.addGestureRecognizer(hamburgerGestureRecognizer)

2) 您可以实现手势识别器的委托功能,并根据呈现的 viewController 有条件地禁用它。像这样的:

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool 
        return currentlyPresentedNavigationController.viewControllers.count == 1
    

【讨论】:

我刚刚意识到这使得汉堡包可以在我的应用程序中的任何位置工作,而不仅仅是在根级别。有没有办法解决这个问题? 请多描述一下。通常有两种方法可以打开汉堡菜单 - 菜单按钮通常放在导航栏的左侧位置。以及来自左边缘的手势(在左侧菜单的情况下)。在菜单按钮情况下。您应该在要使用它的任何 viewController 中提供 leftButtonItem。对于手势识别器,您必须实现委托函数 gestureRecognizerShouldBegin 并仅在您要使用它的级别返回 true。 我已将问题添加到我的主要问题中,在 Edit【参考方案2】:

你需要推动 VC。将根设置为您的 hamburgerMenuVC,然后... 在你的 hamburgerMenuVC 里面做:

let jobListVC = self.navigationController?.childViewController[0] as! jobListController
self.navigationController?.pushViewController(jobListVC, animated: true)

或者:

let jobListVC = jobListController()
self.navigationController?.pushViewController(jobListVC, animated: true)

或者:

let vcs = [jobListController()]
self.navigationController?.setViewControllers(vcs, animated: true)

在 jobListController 中添加视图,而不是 hamburgerMenuVC(创建 CGRect 等)

【讨论】:

代码在第一行失败并出现以下错误:无法将类型“App.homeMenu”(0x102822420)的值转换为“App.jobListController”(0x102821988)。有没有办法让 jobListController 变成导航栏? 检查编辑 - 尝试第二个选项,或者...尝试添加新导航:let 2navVC = UINavigationController(rootViewController: jobListController()) self.present(2navVC, animated:true, completion: nil) 哦,对不起,名字中没有“2”。这是怎么回事。 这部分有效,它确实推送到 jobListController,这很棒,但是我坚持将视图添加到 jobListController,因为控制 hamburgerMenu 的所有手势都在我的 hamburgerMenuVC 中 哦,是的,因为我们创建了一个新的导航。对我来说,我的答案中的第二个选项应该可以正常工作吗?具有 hamburgerMenuVC 根的实际 navigationController 推送到另一个 VC - jobListVC - 它应该在故事板或另一个文件中声明视图,例如jobList.swift - 在 jobListVC viewDidLoad - view = jobList()

以上是关于导航栏未显示在 childViewController 内的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 导航栏未显示在模态导航视图中

导航栏未显示在网页上

模态视图导航栏未正确显示

搜索栏未显示在导航栏 iOS 11 上

导航栏未正确显示

Swift 中的 Xcode:导航栏未显示在 UI 集合视图(模拟器)中