1

I'm learning Swift and I'm studying the delegation pattern. I think I understand exactly what is delegation and how it works, but I have a question.

I have a situation where Controller A is the delegate for Controller B.

In controller B I define a delegate protocol. In controller B I set a variable delegate (optional) In controller B I send message when something happens to the delegate Controller A must adopt method of my protocol to become a delegate

I cannot understand if every delegate controller (in this case A) listens for messages sent by controller B or If I have to tell to controller B that A is now his delegate.

I notice that someone use this code (in controller A)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
 if segue.identifier == "Example" {
 let navigationController = segue.destinationViewController as UINavigationController
 let controller = navigationController.topViewController as AddItemViewController
controller.delegate = self
 }
}

Is this the only way to tell a delegator who is his delegate?

Roberto Pezzali
  • 2,484
  • 2
  • 27
  • 56
  • There's never only one way of doing something. But, what's wrong with that solution? – redent84 Sep 02 '15 at 08:29
  • http://stackoverflow.com/questions/6168919/how-do-i-set-up-a-simple-delegate-to-communicate-between-two-view-controllers pls see this answer this is best answer to understand delegates – shafi Sep 02 '15 at 08:40
  • @shafi the OP said he's learning **Swift** and you are referring to Objective-C answer. That's quite useless, isn't it? – Michal Sep 02 '15 at 08:45

3 Answers3

0

I believe, you need to tell a deligator who is its delegate upon creation of that it. Now, the delegator can be created programatically or through storyboard. So, based on that you have two options, you can tell it who is its delegator programatically like you showed in the code or from IB.

The key here is upon creation. Let's me explain myself. Take the case of a UIView. Say, you want a Custom UIView object(CustomView). So, you drag and drop a UIView in your View Controller and in the identity inspector, you assign its class as of your CustomView's class. So, basically, as soon as the controller is created, your custom view will also be created. Now, you can either say it that the View Controller in which it is created is its delegate or You can go to the IB and connect the view's delegate to the View Controller.

Now, let's assume that you wanted the custom view to be created in your ViewController programatically. In that case, you would probably call the -initWithFrame: method to create the view and upon creation you tell that delegator that who is its delegate like-

myCustomView.delegate = self; 

same goes with a View Controller.

 controller.delegate = self;

So, basically to tell a delegator who is its delegate, you first need that delegator to be created. At least, that's what I think.

Natasha
  • 6,651
  • 3
  • 36
  • 58
0

I think one of the best example of delegation is UITableView.

Whenever you want the control of various properties of a tableView e.g. rowHeight etc, you set your controller to be the delegate of your tableview. To set the delegate of your tableView you need to have tableView created obviously as pointed out by @natasha.

So in your case, you can set delegate of your delegator when you create it or when you find a need for the controller to be delegate of your delegator but you definitely need your delegator to be present to set its property.

You can set your controller as delegate at any time when you require control.

Krishna
  • 770
  • 2
  • 8
  • 21
0

I'm sure you want your UIViewController to act like described, but here is a simpler example how to use the delegation pattern with custom classes:

protocol ControllerBDelegate: class {

    func somethingHappendInControllerB(value: String) 
    /* not optional here and passes a value from B to A*/ 
    /* forces you to implement the function */
}

class ControllerB {

    var delegate: ControllerBDelegate?

    private func someFunctionThatDoSomethingWhenThisControllerIsAlive() {

        /* did some magic here and now I want to tell it to my delegate */
        self.delegate?.somethingHappendInControllerB(value: "hey there, I'm a magician")
    }

    func doSomething() {

        /* do something here */
        self.someFunctionThatDoSomethingWhenThisControllerIsAlive() 
        /* call the function so the magic can really happen in this example */
    }
}

class ControllerA: ControllerBDelegate {

    let controllerB = ControllerB()

    init() {

        self.controllerB.delegate = self /* lets say we add here our delegate*/
        self.controllerB.doSomething() /* tell your controller B to do something */
    }

    func somethingHappendInControllerB(value: String) {

        print(value) /* should print "hey there, I'm a magician" */
    }
}

I wrote the code from my mind and not testet it yet, but you should get the idea how to use such a pattern.

DevAndArtist
  • 4,971
  • 1
  • 23
  • 48