How does a segue create the destination ViewController? - ios

As the question suggests: how does a segue create the destination controller? To be specific, which method gets called? I want to init another ViewController from a nib when a segue creates him. How do I accomplish that?
Thanks a lot

Short answer: initWithCoder: is called.
Longer answer (from apple's docs on UIViewController):
If your app uses a storyboard to define a view controller and its
associated views, your app never initializes objects of that class
directly. Instead, view controllers are either instantiated by the
storyboard—either automatically by iOS when a segue is triggered or
programmatically when your app calls the storyboard object’s
instantiateViewControllerWithIdentifier: method. When instantiating a
view controller from a storyboard, iOS initializes the new view
controller by calling its initWithCoder: method instead. iOS
automatically sets the nibName property to a nib file stored inside
the storyboard.

Related

In iOS, does a segue instantiate the new-to-be-used view controller? Or is it already instantiated?

So for instance, let's say I have a regular subclass of UIViewController and I have connected a control object contained within this controller's view to a segue action that will let another view controller's view come into view...
Simple enough.
When I call the method called prepare(for:sender:) on the regular subclassed UIViewController, at this point, I'm concerned with the new to be used view controller whose view will pop on the screen.. Is this new view controller already instantiated somewhere?
I believe the answer is yes because inside the prepare(for:sender:) function, I set a reference for segue.destination (which is the destination view controller) and when I print that reference, it seems to be a place in memory already which tells me that the new view controller is already instantiated.
Can anyone confirm/deny that this new view controller (created from the storyboard) already has been instantiated, or put this in simpler terms?
Thanks
Apple's documentation says,
When the storyboard runtime detects a custom segue, it creates a new instance of your class, configures it with the view controller objects, asks the view controller source to prepare for the segue, and then performs the segue.
( https://developer.apple.com/reference/uikit/uistoryboardsegue )
So the destination UIViewController is instantiated by the segue just before sending prepareForSegue to the source UIViewController.
So to answer your questions directly, it is "yes" to both questions:
In iOS, does a segue instantiate the new-to-be-used view controller?
Yes, the segue does instantiate the destination view controller.
Or is it already instantiated?
Yes, by the time your prepareForSegue is called, it is already instantiated - immediately beforehand.
UPDATE: As #Jeffery_Thomas commented, this is trivially easy to demonstrate by adding an NSLog() line to your destination view controller's init.
Can anyone confirm/deny that this new view controller (created from the storyboard) already has been instantiated,
Yes. That is what it means to trigger a segue. A triggered segue's job is to instantiate the destination view controller, and prepare exists so that you can configure that instance.

ViewdidLoad called every time

Why every time I change UIViewController embed in UINavigationController using show push in storyboard ViewDidLoad is called?
It hasn't to be called only once or I have to check programmatically if it is already loaded?
Another relative question:
In the following best practices found here in StackOverflow that user are talking about init method, but if my ViewController are loaded by storyboard where I have to initialise my properties?
Best practices
Remember not to do view controller initialisation in viewDidLoad. This is a common mistake. For stuff that should only happen once when the view controller is loaded, do it in one of the controller's init methods.
viewDidLoad is called first time when the viewController's view is loaded, (either by accessing the view controller's view or by presenting a view controller via modal presentation or via a push presentation). Once the view controller is loaded, viewDidLoad will not get called again. If you want to use init method, you need to use initWithCoder for the things that are from storyboard.

How to set Split View Controller Delegate from Storyboard?

I have dragged out a splitViewController, and identified it as a subclass I have created MySplitViewController.
When Right-clicking the splitview storyboard I can see that I've set its Master and Detail view controllers, and furthermore that the delegate is NOT set.
I have made my subclass conform to the protocol and implemented some methods, but they are not being called (which I not understand is because the delegate is not set).
But whenever I try to ctrl+drag from the delegate option in the storyboard to my class, it won't link up. In fact, it won't link up with anything. Am I using this protocol wrong, should my subclass of UISplitViewController not be its own delegate? Then where do I define the delegate in code or otherwise?
Thank you for your time.
Edit: More info-
I tried putting self.delegate = self; in viewDidLoad, but that didn't seem to help.
The particular method I am trying to override is
splitViewControllerPreferredInterfaceOrientationForPresentation:
and I've put an NSLog in the code to notify me if it gets called, which it isn't
As far as I know, NSSplitViewControllers cannot have delegates, and their splitViews can't have their delegates reassigned since the controller acts as the delegate.
If you need access to the delegate methods, simply subclass the controller, then change the class name in Interface Builder.

Segue to a subclass of some view controller

I'm using a storyboard. Let's say I have a view controller that's named MYviewController.
In - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender; I would like to substitute the view controller that I'm segueing to, by one of its child, for example: MYviewControllerChild1 OR MYviewControllerChild2. The child that's segued to depends on the sender parameter.
These view controllers have the same scene (in the storyboard). Only their behaviour is slightly different.
I have a tableView that shows the user the settings of the application. When he clicks a cell, it segues to a viewController where he can modify the value of some setting. Some of theses are alphanumeric, others are numeric. Depending on which cell is clicked, I'd like the input viewController to format the value accordingly (if it's a decimal value I'll use a NSNumberFormatter for example).
Is that possible?
As mentioned in comments to your OP, I believe you should handle this kind of scenario in one viewcontroller.
However, if you insist on using separate controllers, maybe because you think the functionality will be expanded later down the line and therefore add more diversity, you need to handle this by creating multiple storyboard scenes - one for each child controller.
The destination view controller in prepareForSegue is imposed by the viewcontroller at the end of the segue in the storyboard. I don't think there is any way to override that.
As described, your problem isn't really a good candidate for a storyboard. If you use a storyboard you will have to create and sync multiple scenes. Several possible solutions::
Create multiple storyboard scenes and invoke them manually via performSegueWithIdentifier.
Use a nib file instead of a storyboard for this scene. You can use a single nib file since the view controller is created outside the storyboard with [[VCClass alloc] initWithNibFile: bundle: You can create the appropriate view controller class and pass the same nib file to all instances.
Use a single storyboard scene and view controller and pass in typing information in your prepareForSegue.

If you're using a UIStoryboard, will UIViewController call awakeFromNib?

simple question,
If you're using a UIStoryboard, will UIViewController call awakeFromNib?
If not, what is the alternative method being called that we should use?
Cheers!
Yes, awakeFromNib will be called when using a UIStoryboard.
While a .storyboard file is a XML document, it will get converted to a set of traditional .nib files when you compile/package your app, so decoding those will be the same as in xib-based projects.
Yes, awakeFromNib is being called.
According to the documentation:
Initializing a View Controller Loaded from a Storyboard When you
create a view controller in a storyboard, the attributes you configure
in Interface Builder are stored in an archive. Later, when the view
controller is instantiated, this archive is loaded into memory and
processed. The result is a set of objects whose attributes match those
you set in Interface Builder. Here’s how that archive is loaded:
If your view controller implements an initWithCoder: method, that
method is called to process the information in the archive. If your
view controller does not implement an initWithCoder: method, your view
controller’s init method is called instead.
After the objects in the archive are loaded, iOS calls the awakeFromNib method on any objects
that implement such a method. You use this method to perform any
configuration steps that require other objects to already be
instantiated.
Yes awakeFromNib will be called when using a UIStoryboard.

Resources