简体   繁体   中英

How to access a view controller that is not the root view controller from AppDelegate.swift?

I think this is a beginner question. I currently have two view controllers:

class MainViewController: UIViewController {
    var markersToDelete = Marker()
    func deleteMarkers() {}
}

class MapViewController: UIViewController {
    var markersToDelete = Marker()
    func deleteMarkers() {}
}

The MapViewController is instantiated with a modal segue in the storyboard. I know that I can access MainViewController in AppDelegate.swift with this code:

var mainViewController = self.window!.rootViewController as! MainViewController

How can I do the same thing with MapViewController ?

EDIT

Based on the comments below I am updating this to include more detail. Here is what I am trying to accomplish:

I have IBActions in both view controllers that appends Marker items to the
markersToDelete array. The method deleteMarkers is used to find the corresponding items in the Core Data persistent store and delete them; it is called by AppDelegate when applicationDidEnterBackground or when applicationWillTerminate.

This is the reason why I want to access both view controllers from app delegate. I am starting to think there could be a better way to do this.

Some other answers suggest ways of insantiating the controller, but they seem incorrect since you mentioned the controller is instantiated through a segue. There is no straight forward way of doing what you want, and for a good reason, it should be hard to access things from unrelated code. In your very simple example, this code would work, given the controllers have already been presented:

var mainViewController = self.window!.rootViewController as! MainViewController
let mapViewController  = mainViewController.presentedViewController

But I would strongly discourage this type of code inside AppDelegate , it makes a lot of assumptions and will break easily if your navigation structure changes. Be more specific about what you're trying to achieve and you may get answers that lead you to a better architecture.

EDIT

Given the new information provided by the asker, this is a proposed solution to the more specific problem:

I understand you have Marker objects in your Core Data context, and you wish to batch delete some of them. What about adding a bool property to Marker class, and setting it to true for the objects you wish to delete. Then, in AppDelegate , you fetch the markers which have that property set to true, and delete them. This way you don't need to mantain an array, and there is no coupling between classes.

You can access your map controller by calling it's storyboard ID, which you'll need to set in Storyboard. Then just do:

let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
var mapViewController = storyboard. instantiateViewControllerWithIdentifier("storyboardID") as! MapViewController

You need to set storyboard ID to your mapViewController . Then You can access it from appDelegate .

let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main",bundle: nil)
var destViewController : UIViewController
destViewController = mainStoryboard.instantiateViewControllerWithIdentifier("YourViewController") as! UIViewController

You should start by encapsulating your code which is responsible for interaction with CoreData framework API.

Create a singleton class like below and use this class only for insertion/deletion/update operations. This way will ensure loose coupling among your view controllers .

You can get reference to the sharedInstance of DataManager in any class. . Using sharedInstance you can call methods related to your Database operations.

class DataManager {
        class var sharedInstance : DataManager {
            struct Singleton {
                static let instance = DataManager()
            }
            return Singleton.instance
    }
    func deleteMarkers() {
    //Your logic here
}
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM