AMAN77 AMAN77 - 3 months ago 22
Swift Question

Swapping centreViewControllers with FloatingDrawers

I am using a third party pod KGFloatingDrawer which is great because it achieves this:

Floating drawer bliss in iOS

and is a reimplementation of JVFloatingDrawer. I used their sample code and the sliding drawers are working great!

BUT

When I first run my app I call one centreViewController with no drawers (Login). Then after login I call a new centreViewController with

appDelegate.centerViewController = appDelegate.navigationBarController()


which only works if I restart the app. Am I missing something?

The logout seems fine though

appDelegate.centerViewController = appDelegate.drawerSettingsViewController()


which puzzles me a bit because then I think I'm on the right track?

Am I supposed to only use normal segues and such first and then only call the drawerViewController?

Here is the other code when setting up the floating drawers :

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

window = UIWindow(frame: UIScreen.mainScreen().bounds)

window?.rootViewController = drawerViewController

window?.makeKeyAndVisible()

return true
}

private var _drawerViewController: KGDrawerViewController?
var drawerViewController: KGDrawerViewController {
get {
if let viewController = _drawerViewController {
return viewController
}
return prepareDrawerViewController()
}
}

func prepareDrawerViewController() -> KGDrawerViewController {
let drawerViewController = KGDrawerViewController()

drawerViewController.centerViewController = drawerSettingsViewController()
drawerViewController.leftViewController = leftViewController()
drawerViewController.rightViewController = rightViewController()
drawerViewController.backgroundImage = UIImage(named: "sky3")

_drawerViewController = drawerViewController

return drawerViewController
}

private func drawerStoryboard() -> UIStoryboard {
let storyboard = UIStoryboard(name: StoryboardIDs.MainStoryBoardID , bundle: nil)
return storyboard
}

private func viewControllerForStoryboardId(storyboardId: String) -> UIViewController {
let viewController: UIViewController = drawerStoryboard().instantiateViewControllerWithIdentifier(storyboardId)
return viewController
}

func drawerSettingsViewController() -> UIViewController {
let viewController = viewControllerForStoryboardId(StoryboardIDs.LoginViewConSid)
return viewController
}

func sourcePageViewController() -> UIViewController {
let viewController = viewControllerForStoryboardId(StoryboardIDs.SettingsViewConID)
return viewController
}

func navigationBarController() -> UIViewController{
let viewController = viewControllerForStoryboardId(StoryboardIDs.NavConSid)
return viewController
}

private func leftViewController() -> UIViewController {
let viewController = viewControllerForStoryboardId(StoryboardIDs.LeftViewConID)
return viewController
}

private func rightViewController() -> UIViewController {
let viewController = viewControllerForStoryboardId(StoryboardIDs.RightViewConID)
return viewController
}

func toggleLeftDrawer(sender:AnyObject, animated:Bool) {
_drawerViewController?.toggleDrawer(.Left, animated: animated, complete: { (finished) -> Void in
// do nothing
})
}

func toggleRightDrawer(sender:AnyObject, animated:Bool) {
_drawerViewController?.toggleDrawer(.Right, animated: animated, complete: { (finished) -> Void in
// do nothing
})
}

func closeDrawer(sender:AnyObject, animated:Bool){
_drawerViewController?.closeDrawer(.Left, animated: animated, complete: { (finished) -> Void in

})
}

private var _centerViewController: UIViewController?
var centerViewController: UIViewController {
get {
if let viewController = _centerViewController {
return viewController
}
return drawerSettingsViewController()
}
set {
if let drawerViewController = _drawerViewController {
drawerViewController.closeDrawer(drawerViewController.currentlyOpenedSide, animated: true) { finished in }
if drawerViewController.centerViewController != newValue {
drawerViewController.centerViewController = newValue
}
}
_centerViewController = newValue
}
}


Any help/suggestions would be appreciated :D

Answer

Just gonna put this here in case anyone has similar problems.

After a week long struggle to find the problem. I eventually found that whenever I changed the centreViewController with

 appDelegate.centerViewController = appDelegate.navigationBarController()

OR

appDelegate.centerViewController = appDelegate.logoutController()

that the methods

deinit {
     print("deinit called")
    notifCentre.removeObserver(self)
}

were not being called in any of the viewControllers.

So I added the line

self.dismissViewControllerAnimated(false, completion: {})

every time that I change the centreViewController.

Apparently Swift normally deinits automagically but when the using the third party methods there is some confusion with the memory handler and we need to step in. Good to know though as it could be a general swift issue as well.