0

I have a tableview with buttons each containing a tag (according to indexPath.row), and when I press a particular button the details of the contents of that cell (which relates to a class called EventEntity) is meant to be passed through a 'prepareForSegue' method to another screen.

The value is assigned in the 'infoButtonDidPress' method as shown below:

func infoButtonDidPress(sender: UIButton){
    eventPressed = eventEntities[sender.tag]
println (eventPressed.name) // prints the name, all good here.
}

The problem is that when I assign the contents of eventPressed to the destinationVC in 'prepareForSegue', they are nil. Code below:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "infoButtonSegue"){
        var svc = segue.destinationViewController as! EventDetailsViewController;

    println (eventPressed.name) // NOPE.
    svc.name = eventPressed.name //also NOPE!
}

eventPressed is declared above viewDidLoad:

var eventPressed: EventEntity! = EventEntity()

The error I get when I try either of those lines with the 'NOPE' comment is 'Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Appname.EventEntity name]: unrecognized selector sent to instance 0x7fa280e16a50' error

Whats going on here?

Thanks in advance!

UPDATE

I have moved performWithSegue to the infoButtonDidPress method, but I am now unable to reference the destinationViewController.

My infoButtonDidPress now looks like this:

func infoButtonDidPress(sender: UIButton){
   let eventPressed = eventEntities[sender.tag]

   var destinationViewController: UIViewController = self.destinationViewController as EventDetailsViewController
 // error: the current VC does not have a member named destinationViewController

   self.performSegueWithIdentifier("infoButtonSegue", sender: self)
}
vacawama
  • 150,663
  • 30
  • 266
  • 294
Glenncito
  • 902
  • 1
  • 10
  • 23
  • 1
    When you put `let` in front of eventPressed in the function, you are creating a new variable for this scope. Instead just do `eventPressed = eventEntities[sender.tag]` – Shamas S Jul 19 '15 at 21:43
  • I changed it, I still get the 'Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Appname.EventEntity name]: unrecognized selector sent to instance 0x7fa280e16a50' error – Glenncito Jul 19 '15 at 21:47
  • 1
    Looks like a scope thing to me. Do you declare it with var within viewDidLoad? In that case the global var is still not declared. Try to remove var and see if that changes it. – Julia Will Jul 19 '15 at 21:51
  • @JuliaWill no, I declare it above viewDidLoad. – Glenncito Jul 19 '15 at 21:55
  • 1
    try to set a breakpoint and then in the debugger po eventPressed. – Julia Will Jul 19 '15 at 22:14
  • I don't know why I didn't catch this earlier... Basically whats happening is that the prepare for segue method is being called before 'infoButtonDidPress'. infoButtonDidPress is a function targeted by 'infoButton.addTarget etc. ' How do I make that function get called first? – Glenncito Jul 19 '15 at 22:20

1 Answers1

1

As you discovered, prepareForSegue is happening before infoButtonDidPress is called.

To fix this, instead of wiring the segue from the prototype cell in your tableView, wire it from the viewController icon at the top.

See this: How to wire segue from ViewController icon

Make sure to set the identifier to "infoButtonSegue". Then call the segue from infoButtonDidPress after you have set the value for eventPressed:

func infoButtonDidPress(sender: UIButton){
    eventPressed = eventEntities[sender.tag]
    self.performSegueWithIdentifier("infoButtonSegue", sender: self)
}

And then, in prepareForSegue pass the value to the destination view controller:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "infoButtonSegue") {
        let dvc = segue.destinationViewController as! EventDetailsViewController

        dvc.name = eventPressed.name
    }
}
Community
  • 1
  • 1
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • As I also discovered, you are awesome. Thanks! – Glenncito Jul 19 '15 at 22:58
  • will I still use var svc = segue.destinationViewController as! EventDetailsViewController; and then 'svc.variableName' to reference the variables in the target VC? – Glenncito Jul 19 '15 at 23:09
  • 1
    Yes, it's still the same. I would suggest calling your variable `dvc` for "destination view controller" instead of `svc` for "source view controller". But yes, you set it up the same way even if you call the segue programmatically. – vacawama Jul 19 '15 at 23:11
  • The 'segue' bit in 'segue.destinationViewController' doesn't work. How would I reference the UIStoryBoardSegue argument in this case? – Glenncito Jul 20 '15 at 08:46
  • Edit your question showing your latest `prepareForSegue` code. What do you mean "it doesn't work"? Are you getting a compile error or a runtime error? – vacawama Jul 20 '15 at 09:27
  • 1
    Your `infoButtonDidPress` should look exactly as I stated in my answer. You still need a separate `prepareForSegue` function to do the actual setup. – vacawama Jul 20 '15 at 09:41