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

IosObjective CUiviewcontrollerSwiftIos8

Ios Problem Overview


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?

Ios Solutions


Solution 1 - Ios

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.

Solution 2 - Ios

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
	}
}

Solution 3 - Ios

To improve the occulus's answer:

init() {
     super.init(nibName: nil, bundle: nil)
}

Solution 4 - Ios

Update: add the link

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-init

According to the documentation for iOS, the designated initialiser for UIViewController is initWithNibName: bundle:. >If you subclass UIViewController, you must call the super implementation of this method, even if you aren't using a NIB.

You can do it as follows:

init(objectId : NSManagedObjectID) {

	super.init(nibName: (xib's name or nil'), bundle: nil)

   // other code...
}

or

Declare a new initializer as a convenience initializer:

 convenience init( objectId : NSManagedObjectID ) {

	self.init()

	 // other code...

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSirRupertIIIView Question on Stackoverflow
Solution 1 - IosocculusView Answer on Stackoverflow
Solution 2 - IosKlaasView Answer on Stackoverflow
Solution 3 - IosVyacheslavView Answer on Stackoverflow
Solution 4 - IosNcNcView Answer on Stackoverflow