在iOS上使用MDCBottomNavigationBar切换视图控制器 [英] Switching View Controllers using MDCBottomNavigationBar on iOS

查看:106
本文介绍了在iOS上使用MDCBottomNavigationBar切换视图控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个使用Material Design库底部导航功能的iOS应用.我可以使用底部导航栏获得一个视图控制器来进行编译和显示,但是单击其他选项卡时,无法添加其他视图控制器并在它们之间进行切换.我将所有内容简化为两个文件:一个是我的带有底部导航内容的入口视图控制器,另一个是死掉的简单视图控制器,我实例化了3次以用作三个选项卡的目标.

I'm trying to create an iOS app that uses the Material Design library's bottom navigation feature. I can get a view controller with the bottom navigation bar to compile and display, but I'm unable to add other view controllers and switch between them when clicking the different tabs. I have everything simplified down to two files: One is my entry view controller with the bottom navigation stuff, and the other is just a dead simple view controller that I instantiate 3 times to use as the targets of the three tabs.

当前,我的具体错误是:

Currently, my specific error is:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'headerViewController does not have a parentViewController. Use [self addChildViewController:appBar.headerViewController]. This warning only appears in DEBUG builds'

据我所知,这与我的标签视图有关.如果我注释掉self.viewControllers = [...]的行,那么它将很好地加载,但不会在视图控制器之间切换.

As far as I can tell, this is related to my tab views. If I comment out the line that does self.viewControllers = [...] then it will load just fine, but not switch between view controllers.

我不喜欢这种方法.如果有另一种方法可以做到这一点,我很想知道.我一直无法从文档中学到很多东西,但是如果有其他类似选项卡的Material Design功能文档,它们的工作原理也非常相似,那么我认为这将为我指明正确的方向.

I'm not married to this approach. If there is another way to accomplish this I'd love to know it. I have been unable to learn much from the docs, but if there is documentation for other tab-like Material Design features that works significantly similarly, I think that would point me in the right direction.

这是我的入口视图控制器.我以其中一个示例为基础,并对其进行了大量修改.

Here is my entry view controller. I used one of the examples as a base and heavily modified it.

    import Foundation
import MaterialComponents
import UIKit

class ICEBottomNavController: UITabBarController, MDCBottomNavigationBarDelegate
{
    let appBar = MDCAppBar()
    var colorScheme = MDCSemanticColorScheme()

    // Create a bottom navigation bar to add to a view.
    let bottomNavBar = MDCBottomNavigationBar()

    init()
    {
        super.init(nibName: nil, bundle: nil)
        initCommon()
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
        initCommon()
    }

    func initCommon()
    {
        self.title = "Bottom Navigation (Swift)"

        let statusVC = ICEChildBottomBarViewController( title: "Status", color: UIColor.orange )
        let eventsVC = ICEChildBottomBarViewController( title: "Events", color: UIColor.blue )
        let contactsVC = ICEChildBottomBarViewController( title: "Contacts", color: UIColor.cyan )

        self.viewControllers = [ statusVC, eventsVC, contactsVC ]

        self.addChildViewController( appBar.headerViewController )
        let color = UIColor(white: 0.2, alpha:1)
        appBar.headerViewController.headerView.backgroundColor = color
        appBar.navigationBar.tintColor = .white
        appBar.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]

        //appBar.headerViewController.viewControllers

        commonBottomNavigationTypicalUseSwiftExampleInit()
    }

    func bottomNavigationBar(_ bottomNavigationBar: MDCBottomNavigationBar, didSelect item: UITabBarItem)
    {
        print( "did select item \(item.tag)" )

        self.selectedIndex = item.tag

        //self.viewControllers?[item.tag].addChildViewController( appBar.headerViewController )
        //self.selectedViewController = self.viewControllers?[item.tag]

//      self.viewControllers
    }

    func commonBottomNavigationTypicalUseSwiftExampleInit()
    {
        view.backgroundColor = .lightGray
        view.addSubview(bottomNavBar)

        // Always show bottom navigation bar item titles.
        bottomNavBar.titleVisibility = .always

        // Cluster and center the bottom navigation bar items.
        bottomNavBar.alignment = .centered

        // Add items to the bottom navigation bar.
        let tabBarItem1 = UITabBarItem( title: "Status",   image: nil, tag: 0 )
        let tabBarItem2 = UITabBarItem( title: "Events",   image: nil, tag: 1 )
        let tabBarItem3 = UITabBarItem( title: "Contacts", image: nil, tag: 2 )
        bottomNavBar.items = [ tabBarItem1, tabBarItem2, tabBarItem3 ]

        // Select a bottom navigation bar item.
        bottomNavBar.selectedItem = tabBarItem1;
        bottomNavBar.delegate = self
    }

    func layoutBottomNavBar()
    {
        let size = bottomNavBar.sizeThatFits(view.bounds.size)
        let bottomNavBarFrame = CGRect( x: 0,
                                        y: view.bounds.height - size.height,
                                        width: size.width,
                                        height: size.height )
        bottomNavBar.frame = bottomNavBarFrame
    }

    override func viewWillLayoutSubviews()
    {
        super.viewWillLayoutSubviews()
        layoutBottomNavBar()
    }

    #if swift(>=3.2)
    @available(iOS 11, *)
    override func viewSafeAreaInsetsDidChange()
    {
        super.viewSafeAreaInsetsDidChange()
        layoutBottomNavBar()
    }
    #endif

    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.selectedIndex = 0


        appBar.addSubviewsToParent()

        // Theme the bottom navigation bar.
        MDCBottomNavigationBarColorThemer.applySemanticColorScheme(colorScheme, toBottomNavigation: bottomNavBar);

    }

    override func viewWillAppear(_ animated: Bool)
    {
        super.viewWillAppear(animated)
        self.navigationController?.setNavigationBarHidden( true, animated: animated )
    }
}

// MARK: Catalog by convention
extension ICEBottomNavController
{
    class func catalogBreadcrumbs() -> [String] {
        return ["Bottom Navigation", "Bottom Navigation (Swift)"]
    }

    class func catalogIsPrimaryDemo() -> Bool {
        return false
    }

    func catalogShouldHideNavigation() -> Bool {
        return true
    }
}

我应该通过选项卡切换的简单视图控制器:

And my simple view controllers that should be switched out by the tabs:

import Foundation
import MaterialComponents
import UIKit

class ICEChildBottomBarViewController: UIViewController
{
    //let appBar = MDCAppBar()
    //var colorScheme = MDCSemanticColorScheme()
    var color: UIColor?

    init( title: String, color: UIColor )
    {
        super.init(nibName: nil, bundle: nil)
        self.title = title
        self.color = color
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
    }

    override func viewDidLoad()
    {
        super.viewDidLoad()

        view.backgroundColor = self.color

        //appBar.addSubviewsToParent()
    }

    override func viewWillAppear(_ animated: Bool)
    {
        super.viewWillAppear(animated)
        self.navigationController?.setNavigationBarHidden( true, animated: animated )
    }
}

推荐答案

此代码对我来说很有效,因为它可以制作MDCBottomNavBar并在视图控制器之间切换.但是请确保您正在使用TabBarController.

This code works fine for me for making an MDCBottomNavBar and switching between viewcontrollers. But make sure you are using TabBarController.

import UIKit
import MaterialComponents

class TabBarController: UITabBarController, MDCBottomNavigationBarDelegate {

    let bottomNavBar = MDCBottomNavigationBar()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func viewWillAppear(_ animated: Bool)
    {
        super.viewWillAppear(animated)
        self.navigationController?.setNavigationBarHidden( true, animated: animated )
    }

    //Initialize Bottom Bar
    init()
    {
        super.init(nibName: nil, bundle: nil)
        commonBottomNavigationTypicalUseSwiftExampleInit()
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
        commonBottomNavigationTypicalUseSwiftExampleInit()
    }

    // Bottom Bar Customization
    func commonBottomNavigationTypicalUseSwiftExampleInit()
    {
        view.backgroundColor = .lightGray
        view.addSubview(bottomNavBar)

        // Always show bottom navigation bar item titles.
        bottomNavBar.titleVisibility = .always

        // Cluster and center the bottom navigation bar items.
        bottomNavBar.alignment = .centered

        // Add items to the bottom navigation bar.
        let tabBarItem1 = UITabBarItem( title: "Status",   image: nil, tag: 0 )
        let tabBarItem2 = UITabBarItem( title: "Events",   image: nil, tag: 1 )
        let tabBarItem3 = UITabBarItem( title: "Contacts", image: nil, tag: 2 )
        bottomNavBar.items = [ tabBarItem1, tabBarItem2, tabBarItem3 ]

        // Select a bottom navigation bar item.
        bottomNavBar.selectedItem = tabBarItem1;
        bottomNavBar.delegate = self
    }


    func bottomNavigationBar(_ bottomNavigationBar: MDCBottomNavigationBar, didSelect item: UITabBarItem)
    {
        self.selectedIndex = item.tag
    }

    override func viewWillLayoutSubviews()
    {
        super.viewWillLayoutSubviews()
        layoutBottomNavBar()
    }

    #if swift(>=3.2)
    @available(iOS 11, *)
    override func viewSafeAreaInsetsDidChange()
    {
        super.viewSafeAreaInsetsDidChange()
        layoutBottomNavBar()
    }
    #endif

    // Setting Bottom Bar
    func layoutBottomNavBar()
    {
        let size = bottomNavBar.sizeThatFits(view.bounds.size)
        let bottomNavBarFrame = CGRect( x: 0,
                                        y: view.bounds.height - size.height,
                                        width: size.width,
                                        height: size.height )
        bottomNavBar.frame = bottomNavBarFrame
    }

}

这篇关于在iOS上使用MDCBottomNavigationBar切换视图控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆