Ali
Ali

Reputation: 5111

Swift (Xcode) - Pass Value to Next Controller From Table Cell -> Action Button -> Segue

I have table view and in each cell have a button which opens up an action sheet. Once that action sheet opens up there is an action "Report Progress". When I press that action button, I want to open another view controller having segue identifier "ShowProgressReport". In that new view controller I have a property "ProjectName" which is empty by default. I want that property to get value from previous view controller. But I am unable to get index value in "prepareForSegue" method. Here's what I have coded:

TableView

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

        let cell = tableView.dequeueReusableCellWithIdentifier("ProjectViewCell", forIndexPath:indexPath) as! ProjectTableViewCell

        // Remove indenting of cell
        cell.separatorInset = UIEdgeInsetsZero
        cell.layoutMargins = UIEdgeInsetsZero

        // Set project name
        cell.ProjectName.text = self.ProjectsArray[indexPath.row] as? String

        // Set action button
        cell.ActionButton.tag = indexPath.row
        cell.ActionButton.addTarget(self, action: #selector(ProjectsController.projectActions(_:)), forControlEvents: .TouchUpInside)

        return cell

    }

Button Action Sheet

@IBAction func projectActions(sender: UIButton) {
        let index = sender.tag

        let optionMenu = UIAlertController(title: nil, message: self.ProjectsArray[index] as? String, preferredStyle: .ActionSheet)

        // Report Progress
        let reportProgressAction = UIAlertAction(title: "Report Progress", style: .Default, handler: {
            (alert: UIAlertAction!) -> Void in
            self.performSegueWithIdentifier("ShowReportProgress", sender: self)
        })

        // Cancel
        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
            (alert: UIAlertAction!) -> Void in

        })

        optionMenu.addAction(reportProgressAction)
        optionMenu.addAction(cancelAction)

        self.presentViewController(optionMenu, animated: true, completion: nil)
    }

Perform Segue

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

        let index = sender?.tag

        if segue.identifier == "ShowReportProgress"
        {
            let upcoming: ReportProgressController = segue.destinationViewController as! ReportProgressController

            let ProjectName = self.ProjectsArray[index!] as? String --> Here it says: fatal error: unexpectedly found nil while unwrapping an Optional value
            upcoming.ProjectName = ProjectName!
        }

    }

Any help?

Upvotes: 1

Views: 644

Answers (2)

vadian
vadian

Reputation: 285079

In this line

self.performSegueWithIdentifier("ShowReportProgress", sender: self)

you are passing self which represents the view controller. You probably mean to pass the button.

self.performSegueWithIdentifier("ShowReportProgress", sender: sender)

You should always use optional bindings to avoid crashes and unwrap values which are guaranteed to exist.

if let button = sender where segue.identifier == "ShowReportProgress" {
    let upcoming: ReportProgressController = segue.destinationViewController as! ReportProgressController

    let ProjectName = self.ProjectsArray[button.tag] as! String
    upcoming.ProjectName = ProjectName
}

Upvotes: 2

Sahil
Sahil

Reputation: 9226

Replace this

self.performSegueWithIdentifier("ShowReportProgress", sender: self)

With

self.performSegueWithIdentifier("ShowReportProgress", sender: sender)

You're passing controller ref instead of button ref in performSegueWithIdentifier.

Upvotes: -1

Related Questions