5

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!]
      }
Community
  • 1
  • 1
jjjjjjjj
  • 4,203
  • 11
  • 53
  • 72

2 Answers2

3

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.

AlexZd
  • 2,152
  • 2
  • 18
  • 29
  • this is closer, but still not exactly it. The only problem is that the string I need to transfer is in the view controller. It is an index in an array, and the array is only present in the view controller. In this solution the string is here: @IBAction func buttonTapped(sender: AnyObject) { let string = "" self.delegate.actionButtonTapped(string) } so the string can not be transferred still – jjjjjjjj Sep 05 '15 at 20:34
  • 1
    @joey you can add a property to your cell class and assign it in cellForRowAtIndexPath method. Usually you need to pass your object to UITableViewCell class and do some mapping inside cell class. So you can get you object (or object property) inside cell. – AlexZd Sep 06 '15 at 04:43
0

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.

Bhavesh Nayi
  • 3,626
  • 1
  • 27
  • 42
jjjjjjjj
  • 4,203
  • 11
  • 53
  • 72
  • i think it will work for Apple. In case if you want it to be UIButton (if you still need some button features) instead of UILabel you can turn off userInteraction for button in IB. You will get same result. But in this way it will also work if user tap any place in cell. – AlexZd Sep 06 '15 at 04:45
  • ok thanks for the tip. Even the other answer didn't completely answer the question I upvoted it since it did clearly explain how to create and use a delegate (which I didn't understand before). – jjjjjjjj Sep 06 '15 at 05:06