1

This might sound like an odd question but I'm trying to implement the BEMSimpleLineGraph library to generate some graphs that I have place in a UITableView. My question is how I reference an external dataSource and Delegate to have different graphs placed in each cell (BEMSimpleLineGraph is modelled after UITableView and UICollectionView). I currently have something like this:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: FlightsDetailCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as FlightsDetailCell

    cell.userInteractionEnabled = false

    if indexPath.section == 0 {

        cell.graphView.delegate = GroundspeedData()
        cell.graphView.dataSource = GroundspeedData()
        return cell

    }
    if indexPath.section == 1 {

        cell.graphView.delegate = self
        cell.graphView.dataSource = self
        return cell

    }
    return cell
}

My dataSource and Delegate for section 1 is setup properly below this and the GroundspeedData class looks like this:

class GroundspeedData: UIViewController, BEMSimpleLineGraphDelegate, BEMSimpleLineGraphDataSource {

func lineGraph(graph: BEMSimpleLineGraphView!, valueForPointAtIndex index: Int) -> CGFloat {
    let data = [1.0,2.0,3.0,2.0,0.0]
    return CGFloat(data[index])
    }

func numberOfPointsInLineGraph(graph: BEMSimpleLineGraphView!) -> Int {
    return 5
    }
}

For some reason when I run the app, Xcode reports that it cannot find the dataSource for section 0, specifically "Data source contains no data.". How should I otherwise reference this alternate dataSource?

Sam Spencer
  • 8,492
  • 12
  • 76
  • 133
user3185748
  • 2,478
  • 8
  • 27
  • 43

1 Answers1

5
    cell.graphView.delegate = GroundspeedData()
    cell.graphView.dataSource = GroundspeedData()

One problem is: the delegate and data source are weak references. That means they do not retain what they are set to. Thus, each of those lines creates a GroundspeedData object which instantly vanishes in a puff of smoke. What you need to do is make a GroundspeedData object and retain it, and then point the graph view's delegate and data source to it.

Another problem is: do you intend to create a new GroundspeedData object or use one that exists already elsewhere in your view controller hierarchy? Because GroundspeedData() creates a new one - with no view and no data. You probably mean to use a reference to the existing one.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • If, as I am guessing, your problem is that you are not grasping the difference between _instantiating_ a class and getting a reference to an _existing_ instance of that class, my new Swift tutorial has a section about that very matter: http://www.apeth.com/swiftBook/ch04.html#_instance_references – matt Jan 15 '15 at 00:19
  • I have the GroundspeedData class shown above and I am trying to ask my graphView (for a specific section) to take it's delegate and datasource from that class. Does that make sense? The data is already in the class I just need to access it. – user3185748 Jan 15 '15 at 00:19
  • No, @user3185748, there is no such thing as "the data is already in the class". The data is in an _instance_ of the class. That's the whole concept you are not grasping. – matt Jan 15 '15 at 00:20
  • If the problem is even more basic and you don't understand about classes and instances, then you should start earlier in my tutorial, like right at the beginning: http://www.apeth.com/swiftBook/ch01.html#_instances – matt Jan 15 '15 at 00:21
  • I'm just heading out for an hour but when I'm back I'll have a look at the chapter you suggested and see if that helps. – user3185748 Jan 15 '15 at 00:22
  • So I did a bit of reading and came up with the following: `cell.graphView.delegate = self.navigationController?.viewControllers?[0] as BEMSimpleLineGraphDelegate` `cell.graphView.dataSource = self.navigationController?.viewControllers?[0] as BEMSimpleLineGraphDataSource` This gets me the same delegate and dataSource as if I were to indicate just `self`. How do I take it one step further and identify my class? If I change the index to `1` it is out of range. – user3185748 Jan 15 '15 at 01:58
  • Also when I check the parentviewcontroller of the class I've created it returns nil so obviously I'm not able to access it right now, how do I make it available to my app? – user3185748 Jan 15 '15 at 03:18
  • You have not told anything about the architecture of your view controller hierarchy. Only you know where this other view controller is! – matt Jan 15 '15 at 03:19
  • Fair enough. It's a view controller that I created for the sole purpose of providing data to my graph. It's not connected to any views although it resides in the same file as the UITableView view controller. Is it still possible to access it in this manner if it is declared but not connected to my interface at all? – user3185748 Jan 15 '15 at 03:21
  • If it isn't connected to a view then in what sense is it a view controller? And where does it get its data? – matt Jan 15 '15 at 03:40
  • I just made it a viewController because I was getting an error otherwise and it's data is from a file saved to the documents directory on the device. For the moment I've made it work by holding the additional datasource and delegate in the AppDelegate. I don't believe this to be good practice so I will be looking for an alternate but this will keep me moving forward for the moment – user3185748 Jan 15 '15 at 03:45
  • Good choice, because, as I've been telling you, that is an object you can get a reference to! – matt Jan 15 '15 at 03:50
  • Well I appreciate the encouragement haha. Thank you for taking the time today to answer my questions. Have a great night! – user3185748 Jan 15 '15 at 04:02