0

I am trying to get to grips with delegates but the delegate I have set up seems to be nil and I am not sure why. I have a HomeViewController where the game is started from, then a UITableViewController where the player selects a row from a table. The row index is then used to pull data to be used in the game. The UITableViewController segues back to the HomeViewController where the game then starts. I thought I had put the correct protocol and delegate code in place but the delegate seems to be nil. Any help much appreciated!

import UIKit
import Foundation

class HomeViewController: UIViewController, WordListsTableViewControllerDelegate {

override func viewDidLoad() {
     super.viewDidLoad()
     // sets up the game here
}

func wordListSelected(selectedWordList: Int) {
        // passes the index path of the table to the AppWordList class to create the wordList for the game.
        controller.wordList = AppWordList(wordListNumber: selectedWordList)

}

and in the TableViewController

import UIKit

protocol WordListsTableViewControllerDelegate {
    func wordListSelected(selectedWordList: Int)
}

class WordListsTableViewController: UITableViewController {

var delegate: WordListsTableViewControllerDelegate?

override func viewDidLoad() {
    super.viewDidLoad()
    reloadData()
    tableView.reloadData()
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        var selectedWordList = Int()

        if (indexPath.section) == 2 {
            selectedWordList = (indexPath.row) // Console shows the row is being selected ok.
            delegate?.wordListSelected(selectedWordList) // IS NIL ???     
            // exit segue back to the HomeVC
            performSegueWithIdentifier("startGameSegue", sender: nil)

        }
}
Victor Sigler
  • 23,243
  • 14
  • 88
  • 105
richc
  • 1,648
  • 5
  • 20
  • 48

3 Answers3

2

You need to inform the HomeViewController class that has to be the delegate receiver for the class WordListsTableViewController, like this:

import UIKit
import Foundation

class HomeViewController: UIViewController,   WordListsTableViewControllerDelegate 
{
var wordListTableViewController = WordListTableViewController() // You forgot this

override func viewDidLoad() {
    super.viewDidLoad()
    wordListTableViewController.delegate = self   // And this
    // sets up the game here
  }

  func wordListSelected(selectedWordList: Int) {
    // passes the index path of the table to the AppWordList class to create    the wordList for the game.
    controller.wordList = AppWordList(wordListNumber: selectedWordList)
}
Adda_25
  • 498
  • 7
  • 12
1

You're missing a very important point about the Delegate Pattern, you need to keep a reference to the class that delegate its function and set it delegate in the class that handle the function. So let suppose you present the WordListsTableViewController by a segue from the HomeViewController like in the following example:

class HomeViewController: UIViewController, WordListsTableViewControllerDelegate {

  // the reference to the class that delegate
  var wordListTableViewController: WordListsTableViewController!

  override func viewDidLoad() {
      super.viewDidLoad()
     // sets up the game here
  }

  func wordListSelected(selectedWordList: Int) {
     // passes the index path of the table to the AppWordList class to create the wordList for the game.
     controller.wordList = AppWordList(wordListNumber: selectedWordList)
  }

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)    {
      // get the reference to the WordListsTableViewController
      self.wordListTableViewController = segue.destinationViewController as! WordListsTableViewController

      // set as it delegate
      self.wordListTableViewController.delegate = self
  }
}

And then you should be notified from the WordListsTableViewController, in the above example I assume the use of segues, but if you present the WordListsTableViewController you can use the same principle of keep a reference to the delegate class, like I show in the above example.

I do not apply any concept in code regarding the retain-cycles that can be happen in the use of delegates, but you can read more in my answer of this question about how to implement delegates correctly:

I strongly recommend you read more about the Delegate Pattern in this post:

I hope this help you.

Community
  • 1
  • 1
Victor Sigler
  • 23,243
  • 14
  • 88
  • 105
  • Many thanks Victor, I indeed missed the Delegator set up. – richc Nov 23 '15 at 16:45
  • @richc You're welcome but I strongly recommend you read the my answer in the question I post it and the comments in the answer about the correct implementation of the pattern delegate, it could help you for future implementations. – Victor Sigler Nov 23 '15 at 16:49
0

In your HomeViewController you have to set delegate to self:

override func viewDidLoad() {
     super.viewDidLoad()

     // get reference to your word lists table view controller
     // if controller is your table view that should work 
     // controller.delegate = self
    let wordLists = WordListsTableViewController....
    // set up delegate
    wordLists.delegate = self.
}
Greg
  • 25,317
  • 6
  • 53
  • 62