0

I'm trying to call a function on a root view controller from a popover view controller. The function below works but it seems there should be a better way:

func doSomethingInRoot() {
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
        let currentRoot = appDelegate.window!.rootViewController as? RootViewController {
            currentRoot.somefunction()
    }
}

In the above code, doSomethingInRoot would be contained in the popover, and someFunction would be a function of RootViewController.

What I'm looking for is a way to pass someFunction to another function that contains the if let above, however, the problem is currentRoot is only assigned as a RootViewController within the above (i.e., doSomethingInRoot doesn't know that it's being passed a method of RootViewController instead of a generic function).

In writing this question, I realized that I could do the following, which feels pretty clean, but I'm still curious whether I can pass a method to a specific class as parameter.

func doSomethingInRoot() {
    if let root = getRoot() {
        root.someFunction()
    }
}

func getRoot() -> RootViewController? {
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
        let currentRoot = appDelegate.window!.rootViewController as? RootViewController {
        return currentRoot
    } else {
        return nil
    }
}
SuperCodeBrah
  • 2,874
  • 2
  • 19
  • 33
  • btw getRoot can just be implemented as `return (UIApplication.shared.delegate as? AppDelegate)?.window?.rootViewController as? RootViewController`. It's also preferable to us a computed property over a function for soemthing like this – Alexander Jan 05 '18 at 03:44
  • Check out delegation pattern – JustinM Jan 05 '18 at 04:56

1 Answers1

1

In your popover view controller, you could add a property like this to hold the reference to someFunction

var rootsSomeFunction: (()->Void)!

Then assign the reference when creating the popover VC whether it's in prepareForSegue, or after you instantiate if from storyboard...etc. I'd also move getRoot() to the App Delegate.

popoverVC.rootsSomeFunction = appDelegate.getRoot().someFunction().self

Finally, in your popover view controller, you can call it by the property like this:

self.rootsSomeFunction()
Ahmed Hamed
  • 504
  • 1
  • 3
  • 11