Swift: my delegate protocol methods must be executed on another view controller

This is a really confusing problem, so I will try to explain it as best I can.

I have view controllers A, B, C, D and E

I'm not sure if I said this correctly, but to rephrase this, E needs to talk to A, but there is no choice between A and E to set up a delegate.

A> B> C> D> E> A

I was told that when you use delegates to quickly access data between view controllers, you must have a few things:

  • Define the delegate protocol for object B.
  • Give object B an extra delegate variable. This variable must be weak.
  • Make object B send messages to its delegate when there is something interesting, such as the user clicking Cancel or Done, or when he needs information.
  • Make object A conform to the delegate protocol. It must specify the name of the protocol in its class line and implement the methods from the protocol.
  • Tell object B that object A is now its delegate.

I use prepapreforsegue to pass an object between view controllers as they move from one to the other, adding to it as they continue with the prepareforsegue method.

In the final view controller, I have protocol methods designed to start the first view controller, but since the last view controller exits from another view controller. The problem is that these methods are supposed to be used on the first view controller. How can he achieve this without the first view controller being able to tell the last view controller that he is passing through.

Here's some simple code to show you my problem and what I mean.

Firstly:

import UIKit

class FirstViewController: UITableViewController, LastViewControllerDelegate {

var entry: EntryItem!

override func viewDidLoad() {
    super.viewDidLoad()
    entry = EntryItem()
    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

...

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    //here where I access the next view controller and set controller.entry and controller.delegate
    let controller = segue.destinationViewController as NextViewController
    controller.entry = entry
}

func lastViewControllerDidCancel(controller: LastViewController, didNotFinishAddingEntry draftentry: EntryItem){
    //this is where I wanna do something
    dismissViewControllerAnimated(true, completion: nil)
}
func lastViewController(controller: LastViewController, didFinishAddingEntry finalentry: EntryItem){
    //this is where I wanna do something
    dismissViewControllerAnimated(true, completion: nil)
}
}

      

Next 1:

import UIKit


class Next1ViewController: UITableViewController, LastViewControllerDelegate {

var entry: EntryItem!

override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

...

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    //here where I access the next view controller and set controller.entry and controller.delegate
    let controller = segue.destinationViewController as Next2ViewController
    controller.entry = entry
}


}

      

Next 2:

import UIKit


class Next2ViewController: UITableViewController, LastViewControllerDelegate {

    var entry: EntryItem!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

    ...

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        //here where I access the next view controller and set controller.entry and controller.delegate
        let controller = segue.destinationViewController as LastViewController
        controller.entry = entry
        controller.delegate = ???? //Not self, but needs to be the first one.
    }


}

      

Last:

import UIKit

protocol LastViewControllerDelegate: class {
    func lastViewControllerDidCancel(controller: LastViewController, didNotFinishAddingEntry draftentry: EntryItem)
    func lastViewController(controller: LastViewController, didFinishAddingEntry finalentry: EntryItem)
}

class LastViewController: UITableViewController {

weak var delegate: LastViewControllerDelegate?
var entry: EntryItem!

override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

...


@IBAction func cancel(){
    delegate?.lastViewControllerDidCancel(self, didNotFinishAddingEntry: entry)
}

@IBAction func done(){
    //do some final additions to entry object
    delegate?.lastViewController(self, didFinishAddingEntry: entry)
}

}

      

+3


source to share


1 answer


Can't you get your first view controller to conform to all of the delegate protocols (or maybe make one delegate protocol, otherwise you'll get casting issues) and then instead:

controller.delegate = self

      

Just do



controller.delegate = self.delegate

      

Alternatively, if you have multiple steps removed, using notifications is often better than delegating. If intermediate view controllers have no purpose for a delegate other than to forward it, you should use notifications.

+2


source







All Articles