0

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!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
bitwise
  • 1
  • 3

4 Answers4

0

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
        }
    }
}
ZHZ
  • 2,088
  • 13
  • 16
0

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.

Wingzero
  • 9,644
  • 10
  • 39
  • 80
  • Sorry, by, "this does not work" I mean that after I call presentViewController(...) the viewDidLoad() method of the myViewController is called but the properties are nil (i.e. @IBOutlet weak var itemTextField: UITextField!) and it doesn't load in the simulator (just a black screen). The "item" *is* populated so the data does get passed, but it's not constructing the view controller properly as it does in prepareForSegue(...), which can load that same view controller just fine when a new "item" is added via my "AddItem" segue that I sent up in Interface Builder. – bitwise Dec 02 '15 at 04:25
  • it's totally a different issue then. Seems your view controller is not properly setup. You should check your itemViewController first. If you push or just set the root view controller to itemViewController, can you see the UI? if you cannot handle it, post your code and screenshots of your xib or storyboard so we can know. – Wingzero Dec 02 '15 at 05:40
0

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?

Nguyen Hoan
  • 1,583
  • 1
  • 11
  • 18
0

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)
Community
  • 1
  • 1
bitwise
  • 1
  • 3