Hey everyone,
Based on James Frost’s excellent tutorial on creating a slide-out navigation panel (https://www.raywenderlich.com/78568/create-slide-out-navigation-panel-swift) I’ve been working on a version of that code that’s essentially closer to what the Facebook app’s navigation was in the version presented in the above tutorial.
What I essentially did was create a ContainerViewController, a MasterViewController, a single left SidePanelViewController and three child/sub view controllers: FirstViewController, SecondViewController, ThirdViewController that are being displayed in the MasterViewController after selecting a table cell of the SidePanelViewController. I figured the most efficient way of creating those child view controllers would be after the SidePanelViewController’s cell has been selected to display that particular child view controller. However the approach I managed to implement does smell bad even to a beginner such as myself.
Here’s the gist of the code which is very easy to understand.
// MainViewController.swift
class MainViewController: UIViewController {
var firstViewController: FirstViewController?
var secondViewController: SecondViewController?
var thirdViewController: ThirdViewController?
var viewControllers = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
instantiateViewController(withIndex: 0)
}
}
extension MainViewController {
func instantiateViewController(withIndex index: Int) {
if index == 0 {
if firstViewController == nil {
firstViewController = UIStoryboard.firstViewController()
view.addSubview(firstViewController!.view)
addChildViewController(firstViewController!)
firstViewController!.didMove(toParentViewController: self)
viewControllers.append(firstViewController!)
}
} else if index == 1 {
if secondViewController == nil {
secondViewController = UIStoryboard.secondViewController()
view.addSubview(secondViewController!.view)
addChildViewController(secondViewController!)
secondViewController!.didMove(toParentViewController: self)
viewControllers.append(secondViewController!)
}
} else if index == 2 {
if thirdViewController == nil {
thirdViewController = UIStoryboard.thirdViewController()
view.addSubview(thirdViewController!.view)
addChildViewController(thirdViewController!)
thirdViewController!.didMove(toParentViewController: self)
viewControllers.append(thirdViewController!)
}
}
}
func cycleFromViewController(oldVC: UIViewController, newVC: UIViewController) {
addChildViewController(newVC)
oldVC.willMove(toParentViewController: nil)
self.transition(from: oldVC, to: newVC, duration: 0.25, options: .transitionCrossDissolve, animations: nil) { _ in
newVC.didMove(toParentViewController: self)
oldVC.removeFromParentViewController()
}
}
}
extension MainViewController: SidePanelViewControllerDelegate {
func itemSelected(_ index: Int) {
instantiateViewController(withIndex: index)
let oldVc = self.childViewControllers[0]
let newVc = viewControllers[index]
if oldVc != newVc {
cycleFromViewController(oldVC: oldVc, newVC: newVc)
}
delegate?.togglePanel?()
}
}
This does seem to work but it definitely doesn’t look like the best way of doing what I was trying to achieve so figured maybe someone could steer me towards a better implementation of a lazy instantiation of those child view controllers. Any tips would be greatly appreciated.