Home > Software design >  What is the operation of assigning a class to a constant called? Swift, Xcode
What is the operation of assigning a class to a constant called? Swift, Xcode

Time:10-18

I'm trying to figure out the delegate and the protocol and studying the tutorial. It has the following code:

class SelectTimeViewController: UIViewController, PopupDelegate{
...
 let sb = UIStoryboard(name: "DatePopupViewController", bundle: nil) 
 let popup = sb.instantiateInitialViewController() as! DatePopupViewController          
 popup.delegate = self
…
}

What does this line in the code mean?

let popup = sb.instantiateInitialViewController() as! DatePopupViewController

I understand that here we are creating a popup constant and assigning something to it, which is then cast to the DatePopupViewController class.

But what does this mean more generally?

  1. Are we create an instance of the DatePopupViewController class?
  2. Are we assign any value from the DatePopupViewController class?
  3. Anything else?

CodePudding user response:

Your storyboard has one or more scenes. Each scene is managed by a view controller. Usually you'll create a custom UIViewController subclass for each scene. In the storyboard editor, for each scene, you type in the name of that custom class.

One of the scenes in the storyboard can marked as the “initial scene”. UIStoryboard has a method, instantiateInitialViewController, that loads that scene from the storyboard.

But there are lots and lots of storyboards in the world, and they use lots and lots of different custom UIViewController subclasses for their scenes. You might even have multiple storyboards in a single app, each with an initial scene that uses a different custom subclass.

There is no way, at compile-time, for UIStoryboard to know what class the instantiateInitialViewController is going to load. All it knows at compile-time is that it's going to load a UIViewController, or a subclass of UIViewController. So instantiateInitialViewController is declared to return UIViewController.

But when you're writing your code, you usually do know what specific subclass it's going to load, and often you want to do things that depend on the subclass. In the code you posted, you're setting a property named delegate, which is a property specific to DatePopupViewController—it is not a property of UIViewController.

In order to access that delegate property, you need to tell Swift what you know that Swift doesn't already know. You need to tell Swift that you're loading a DatePopupViewController. You do that using syntax called a “cast”:

let popup = sb.instantiateInitialViewController() as! DatePopupViewController 
↑   ↑       ↑  ↑                                  ↑   ↑
|   |       |  This method returns a              |   The subclass you know
|   |       |  UIViewController object. It        |   you're loading.
|   |       |  might be (and usually is) a        |
|   |       |  subclass of UIViewController.      The cast operator.
|   |       |                                     The ! means the program
|   |       This variable references              will crash if the
|   |       a UIStoryboard object,                loaded object is not
|   |       which represents a                    an instance of
|   |       storyboard at runtime.                DatePopupViewController.
|   |
|   This variable gets bound to the
|   newly-loaded DatePopupViewController.
|
This says that the popup variable cannot
be changed to point at a different
instance of DatePopupViewController.

CodePudding user response:

I will explain you the code step by step...

class SelectTimeViewController: UIViewController, PopupDelegate{

Definition of the SelectTimeViewController class, which is a UIViewController and implements the PopupDelegate protocol. SelectTimeViewController can work as a delegate only because of this implemented protocol.

let sb = UIStoryboard(name: "DatePopupViewController", bundle: nil)

Creates a storyboard object from the file DatePopupViewController.storyboard.

let popup = sb.instantiateInitialViewController() as! DatePopupViewController

Instantiates the initial ViewController in this storyboard object. You can identify the initial ViewController by the arrow in the storyboard file. Remember that each view in the storyboard has a ViewController. So you create the view together with the ViewController. In your case the ViewController is the DatePopupViewController.

You could omit as! DatePopupViewController. In this case the popup constant is only of type ViewController and you can't access any attributes of DatePopupViewController.

popup.delegate = self

Your instantiated DatePopupViewController is now assigned to the popup constant. So you can access DatePopupViewController's attributes through the popup constant. We have implemented the PopupDelegate protocol in the first code line. Therefore we can set the current class (SelectTimeViewController) as delegate of DatePopupViewController.

Summary:

  1. Yes, assigned to popup
  2. Yes, delegate of DatePopupViewController
  3. See above

CodePudding user response:

About #1.

Usually, when we create an instance of a class, we use the following syntax:

constant (or variable) = ClassName (initializer)

For example:

var item = Item(name: "Car")

In this case, the syntax is different:

let popup = ... DatePopupViewController

That is, there is no class initializer here.

Why then do we call it creating of class instance?

  • Related