cosmicmindmaterial-swift

FABMenuController to share FAB across view controllers


I am following the CardTableView demo code and its way of embedding view controllers so that the FABMenuController is on top. For some reason, the following code works, until I try to add the FABController:

let tabs = AppPageTabBarController(viewControllers:[InvitedViewController(), CoordinatingViewController(), PastViewController()])
let toolbar = AppToolbarController(rootViewController: tabs)
let root = MyTeeUpsViewController(rootViewController: toolbar, leftViewController: NavDrawerContainerController())
let snackBarController = AppSnackbarController(rootViewController: root)
let fabMenuController = AppFABMenuController(rootViewController: snackBarController)
self.present(fabMenuController, animated: true)

I have implemented the AppFABMenuController just as the demo code has, and it exists, and inherits from the FABMenuController from MaterialSwift. I can't understand why I get the error: fatal error: unexpectedly found nil while unwrapping an Optional value Regarding the view hierarchy I think it makes more sense to embed the SnackbarController last, but even if i do this it still fails on the line that declares let fabMenuController=...


Solution

  • I would approach your setup like so:

    let tabs = AppPageTabBarController(viewControllers:[InvitedViewController(), CoordinatingViewController(), PastViewController()])
    let toolbar = AppToolbarController(rootViewController: tabs)
    let fabMenuController = AppFABMenuController(rootViewController: toolbar)
    let snackBarController = AppSnackbarController(rootViewController: fabMenuController)
    let navDrawer = MyTeeUpsViewController(rootViewController: snackBarController, leftViewController: NavDrawerContainerController())
    self.present(navDrawer, animated: true)
    

    Basically, the NavigationDrawerController should always be the lowest level, or root of your view stack. If you were to set this up with a login, you could setup the NavigationDrawerController as your AppDelegates rootViewController, and disable the side panels. When the user successfully logs in, you could call navigationDrawerController?.transition(to: MyNewVC) and then enable the side panels. This way the login view controller is off the stack and everything is setup. I put the ToolbarController as a child of the FABMenuController so that you can switch between controllers and either add an entirely new top navigation controller or remove it completely. The look and feel of Material usually covers everything on the screen when the FABMenu is displayed. The Snackbar could go above or below the FABMenu, but that is really up to you, visually, it shouldn't ever make a difference.

    As a note, in the latest Material 2.9.*, you no longer need to cast the rootViewController types and you no longer need to search in child view controllers only for the transitioning controller. Meaning, from anywhere, you could now call toolbarController?.transition ... etc.

    Hope this helps :)