Why can't I call the default super.init on UIViewController in Swift?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
When you subclass UIViewController, a plain zero-argument super.init() is not the initializer UIKit wants you to call. UIViewController has designated initialization paths built around init(nibName:bundle:) and required init?(coder:), and Swift enforces those rules through its initializer system.
Why super.init() is not the right call
Swift classes follow designated-initializer chaining. A subclass must ultimately call one of its superclass's designated initializers.
For UIViewController, the important initializer paths are:
- '
init(nibName:bundle:)for programmatic or nib-based creation' - '
init?(coder:)for storyboard and archive decoding'
That is why a custom programmatic initializer usually ends like this:
The subclass initializes its own stored properties first and then calls the correct designated initializer on UIViewController.
What if the controller comes from a storyboard
If the view controller is created from a storyboard, UIKit initializes it through init?(coder:). In that path, you do not get to replace the initialization flow with a custom plain initializer.
A storyboard-based controller therefore often looks like this:
If you need dependency injection with storyboards, you usually inject after instantiation or use newer storyboard creator APIs rather than inventing an unsupported super.init() path.
Why UIKit is designed this way
UIViewController is tied to view loading, nibs, storyboards, state restoration, and internal UIKit lifecycle behavior. UIKit needs specific initialization entry points so it can set up that machinery correctly.
A generic zero-argument superclass initializer would not express whether the controller comes from a nib, from a storyboard archive, or from a fully programmatic configuration.
So the restriction is not arbitrary. It reflects how UIKit constructs controller objects safely.
Initialization is not where view setup belongs
Another source of confusion is trying to use init for work that really belongs in loadView or viewDidLoad. Initializers should establish dependencies and basic state, while view hierarchy setup usually happens later in the controller lifecycle.
That separation is one more reason UIKit keeps controller initialization narrow and explicit.
Another programmatic pattern
Some developers try to create a convenience initializer that still funnels through the proper designated initializer. That is valid as long as the chain eventually reaches init(nibName:bundle:).
The important point is that even this style does not call a bare super.init(). It still goes through the initializer UIKit expects.
Common Pitfalls
A common mistake is assuming every superclass has a meaningful plain init() available to subclasses. Swift only lets you call initializers that actually exist and are valid for the type.
Another issue is mixing storyboard creation with a custom required dependency initializer without planning how that dependency will be provided.
It is also easy to forget that subclass properties must be initialized before calling the superclass designated initializer. Swift's two-phase initialization rules are strict here.
Summary
- '
UIViewControllerdoes not expose a plain superclass initialization path that replacesinit(nibName:bundle:)orinit?(coder:).' - Programmatic view controllers usually call
super.init(nibName:nil, bundle:nil). - Storyboard-created view controllers are initialized through
super.init(coder:). - The initializer you call depends on how the controller is created.
- Swift enforces this to preserve UIKit's required initialization lifecycle.
Related reading
- Why convenience keyword is even needed in Swift?
- Why create Implicitly Unwrapped Optionals, since that implies you know there''s a value?
- Why do I get iOS linker errors with my static libraries?
- Why do I need 1x, 2x and 3x iOS images?
- Why do I need underscores in swift?
- Why do most fields class members in Android tutorial start with m?
- Why do we use use_frameworks in CocoaPods?
- Why does an image captured using camera intent gets rotated on some devices on Android?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.