Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create singleton of a viewcontroller in swift 3

I know how to create singleton class in swift. The best and easy way to create singleton class is the following:

class Singleton {
    static let sharedInstance = Singleton()
}

But I don't need singleton for any normal class. I need to create singleton for a viewcontroller class. So I'm using this code create singleton

class AViewController:UIViewController {

    static let sharedInstance = AViewController()

    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

}

it gives me error near AViewController()

Missing argument for parameter 'coder' in call

Looks like it want me to initialize with init(coder: NSCoder). But what parameter or value should I pass through the coder?

like image 821
Poles Avatar asked Dec 14 '16 07:12

Poles


3 Answers

If you really wanted to have singleton for a view controller corresponding to some scene, you'd probably do something like:

class SecondViewController: UIViewController {

    static let shared = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Foo")

}

In this example, the storyboard was Main.storyboard and the storyboard identifier for the scene in question was Foo. Obviously, replace those values for whatever was appropriate in your case.

Then your other view controller that was invoking this could do something like:

@IBAction func didTapButton(_ sender: Any) {
    let controller = SecondViewController.shared
    show(controller, sender: self)
}

I wouldn't recommend singletons for view controllers. View controllers (and their views) should be created when needed and be allowed to be deallocated when they're dismissed. And you're losing many storyboard benefits (by which you see the logical flow between scenes with segues between them). And, if you use this view controller in different contexts, you're inviting problems stemming from the view controller hierarchy falling out of sync with the view hierarchy. I really would discourage you from using singletons for view controllers.

But if you were going to do it, you could do something like that...

like image 159
Rob Avatar answered Nov 15 '22 04:11

Rob


Try to do:

AppDelegate:

Add a reference to the ViewController, so you can access it globally, like so:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    private var viewController: ViewController?

    func getViewController() -> ViewController {
        if viewController == nil {
            // make sure that the name of the storyboard is "Main"
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            // make sure that you named the viewcontroller in storyboard (Storyboard ID), it is the identifier
            viewController = storyboard.instantiateViewController(withIdentifier: "ViewControllerStoryboardID") as! ViewController
        }

        return viewController!
    }


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    // ....
}

AnotherViewController (Usage):

Now you can access it via "AppDelegate", like so:

class AnotherViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()


        let appDelegate = UIApplication.shared.delegate as! AppDelegate

        let vc = appDelegate.getViewController()
    }

    // ...
}

Hope this helped.

like image 36
Ahmad F Avatar answered Nov 15 '22 04:11

Ahmad F


I would recommend something like:

enter image description here

like image 40
Senocico Stelian Avatar answered Nov 15 '22 06:11

Senocico Stelian