jjjjjjjj
jjjjjjjj

Reputation: 4523

Using delegates to transfer data from one TableView to another

I need to transfer a string from one tableview to another by clicking on a button that is inside a UITableView. I know how to get the indexPath via a button, like so:

    let button = sender as MyButton
    let view = button.superview!
    let cell = view.superview as! MyTableViewCell

    let indexPath = tableView.indexPathForCell(cell)

the above code works to get the indexpath of the cell on a button click, zhowever in order to transfer data, I have to use the prepareForSegue. So naturally I tried to use prepare for segue and change the sender from AnyObject? to MyButton

Then I got an error message saying "overriding method with selector prepareforsegue has incompatible type."

I searched and read about delegates in swift and how these can help, and I tried the answer given by MakeAppPie here:

Delegates in swift? but it did not work for me.

Is there any way to combine the prepare for segue and the code I have above? I tried this, but it resulted in the error message I just mentioned above:

      override func prepareForSegue(segue: UIStoryboardSegue, sender: MyButton)  {

      let myVC = segue.destinationViewController as? CommentsViewController


                   let usender:AnyObject = sender!
                    let button = usender as? MyButton
                    let view = button.superview!
                    myVC!.title = button.titleForState(.Normal)

                    let cell = view.superview as! QuestionCell


                    let indexPath = tableView.indexPathForCell(cell)

                    println(self.short_descriptionArray)

                    var row = self.tableView.indexPathForSelectedRow()?.row
                    myVC!.nameToGet = short_descriptionArray[row!]
      }

Upvotes: 5

Views: 894

Answers (2)

jjjjjjjj
jjjjjjjj

Reputation: 4523

I found an answer/work around. Instead of using a UIButton to perform the segue, I just used a label instead, so when I click on the label, it is registered as a click on the tableview cell. This allowed me to get the index Path via clicking and also properly use prepare for segue to transfer the data needed.

I'm not sure if this will last/be acceptable by Apple whenever I submit it (perhaps misuse of UI elements by using label as a button?), but for the time being it works.

Upvotes: 0

AlexZd
AlexZd

Reputation: 2152

I'm not sure that I got you 100%, but I'll try to help you.

No need to change prepareForSegue: method. You can get what you need from AnyObject. Also I think you will get empty result here:

var row = self.tableView.indexPathForSelectedRow()?.row

Because tapping on your button will not select your cell.

In case you need to handle some action from button inside UITableViewCell you need to add inside your cell class:

protocol MyTableViewCellDelegate : NSObjectProtocol {
    func actionButtonTapped(string:String)
}

class MyTableViewCell: UITableViewCell {
    var delegate : MyTableViewCellDelegate!
    @IBAction func buttonTapped(sender: AnyObject) {
        let string = "<your string>"
        self.delegate.actionButtonTapped(string)
    }
}

Inside your UIViewController:

class MyViewController : UIViewController, MyTableViewCellDelegate {

...

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    ...
    cell.delegate = self
    ...
    return cell
}

func actionButtonTapped(string:String) {
    self.performSegueWithIdentifier("segueIdentifier", sender: string)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let myVC = segue.destinationViewController as? CommentsViewController {
        myVC.nameToGet = sender as! String
    }
}

In case if you need to do the same but by cell tap, it will be much simple, without this protocol stuff.

Upvotes: 3

Related Questions