Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I call the default super.init() on UIViewController in Swift?

I am not using a UIViewController from a storyboard and I want to have a custom init function where I pass in an NSManagedObjectID of some object. I just want to call super.init() like I have in Objective-C. Like this:

init(objectId: NSManagedObjectID) {     super.init() } 

But I get the following compiler error:

Must call designated initializer of the superclass UIViewController

Can I simply not do this anymore?

like image 872
SirRupertIII Avatar asked Jun 07 '14 07:06

SirRupertIII


People also ask

Why we use super init in Swift?

This is called class inheritance or subclassing, the class you inherit from is called the “parent” or “super” class, and the new class is called the “child” class. For safety reasons, Swift always makes you call super. init() from child classes – just in case the parent class does some important work when it's created.

What is convenience init Swift?

Convenience initializers are secondary, supporting initializers for a class. You can define a convenience initializer to call a designated initializer from the same class as the convenience initializer with some of the designated initializer's parameters set to default values.


2 Answers

The designated initialiser for UIViewController is initWithNibName:bundle:. You should be calling that instead.

See http://www.bignerdranch.com/blog/real-iphone-crap-2-initwithnibnamebundle-is-the-designated-initializer-of-uiviewcontroller/

If you don't have a nib, pass in nil for the nibName (bundle is optional too). Then you could construct a custom view in loadView or by adding subviews to self.view in viewDidLoad, same as you used to.

like image 138
occulus Avatar answered Oct 13 '22 15:10

occulus


Another nice solution is to declare your new initializer as a convenience initializer as follows:

convenience init( objectId : NSManagedObjectID ) {     self.init()      // ... store or user your objectId } 

If you declare no designated initializers in your subclass at all, they are inherited automatically and you are able to use self.init() within your convenience initializer.

In case of UIViewController the default init method will call init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) with nil for both arguments (Command-Click on UIViewController will give you that info).

TL;TR: If you prefer to programmatically work with UIViewControllers here is a complete working example that adds a new initializer with a custom argument:

class MyCustomViewController: UIViewController {     var myString: String = ""      convenience init( myString: String ) {         self.init()          self.myString = myString     } } 
like image 31
Klaas Avatar answered Oct 13 '22 14:10

Klaas