简体   繁体   中英

How to pass data to a UIViewController from a UITableViewRowAction in Swift?

I'm new to iOS programming, and I've been searching for how to do this, but can't seem to find what I'm looking for. I thought this would be a fairly easy task, and I'm sure it is if someone can enlighten me.

When you swipe left on a table view I have some custom actions that can be performed. One of those actions is a simple "Edit" of the item selected. All I want to do is display another view controller but pass some data to that view controller like how it's normally done in prepareForSegue(...).

Here is what I have. Please see the section marked "//Option 2" ...

    // Override to provide additional edit actions when the users swipes the row to the left.
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {

    let deleteAction = UITableViewRowAction(
        style: UITableViewRowActionStyle.Normal, title: "Delete", handler: deleteHandler);
    deleteAction.backgroundColor = UIColor.redColor()

    let editAction = UITableViewRowAction(
        style: UITableViewRowActionStyle.Normal, title: "Edit", handler: editHandler);
    editAction.backgroundColor = UIColor.grayColor()

    return [deleteAction, editAction]
}

// Handles the delete action when the users swipes the row to the left.
func editHandler(action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void {

    // Option 1
    //performSegueWithIdentifier("EditItem", sender: nil)

    //Option 2 - This does not work.
    let myViewController = ItemViewController()
    let selectedItem = self.items[indexPath.row] // I have an array of 'items'
    myViewController.item = selectedItem
    self.presentViewController(myViewController, animated: true, completion: nil)
}

// Handles the delete action when the users swipes the row to the left.
func deleteHandler(action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void {
    self.games.removeAtIndex(indexPath.row)
    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}

How can I pass data to my view controller in the "editHandler" method? I can display the view controller all day long using the segue, but I want it to be loaded with the selected item in the table so that it can be modified by the user.

Thanks!

With Option1. You can pass data by sender.

let selectedItem = self.items[indexPath.row] // I have an array of 'items'

performSegueWithIdentifier("EditItem", sender: selectedItem)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "EditItem" {
        let itemViewController = segue.destinationViewController as! ItemViewController
        if let item = sender as? Item {
            itemViewController.item = item
        }
    }
}

Either option 1 or option 2 is using the same technique to pass data, namely creating a new itemViewController instance and assign items to it.

Your code seems fine with option 2, the problem is, what do you mean by 'does not work'? You can add breakpoints at

myViewController.item = selectedItem

and print out myViewController and item to see if thay are what you want. Then in myViewController 's viewDidLoad method, check if the item is still valid.

If everything is fine, you should be good.

I think, your problem is not

    //Option 2 - This does not work.
    let myViewController = ItemViewController()
    let selectedItem = self.items[indexPath.row] // I have an array of 'items'
    myViewController.item = selectedItem
    self.presentViewController(myViewController, animated: true, completion: nil)
}

i'm sure it's correct. So Do I
In your myViewController, you try print item in viewdidload to check it have data?

So I figured out the problem from a combination of discovering that I had a different issue going on then what I originally thought, and with the information in this post: Swift presentViewController

My view controller was embedded in a navigation control, and this requires some extra setup when creating the view controller. I had to assign a "Storyboard ID" in the view controllers Identity Inspector (I assigned the id of "EditItem"), and then I had to instantiate the view controller with that ID and embed it in a navigation controller...

    let itemViewController = self.storyboard?.instantiateViewControllerWithIdentifier("EditItem") as! ItemViewController
    itemViewController.item = self.items[indexPath.row]
    let navigationController = UINavigationController(rootViewController: itemViewController)
    self.presentViewController(navigationController, animated: true, completion: nil)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM