Need Help Transfer Data From Button

I am not sure how to transfer data a name from a button in my UITableViewCell to a UIViewController. I have a prepare function but it doesn't work gives me an unrecognized selector error. Is there a way to use it for this instance?

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "hs" {
    let destinationController = segue.destination as! HighlightsVC
      destinationController.playerName = (item.yahooName!)
  }
  }

Replies

I analyzed it and there's 2 segues that are going to the VC. So that's why it's being called twice. I have to get rid of the button action and do a segue with storyboard.

  • gotta figure out why the name is not being transferred over.

Add a Comment

gotta figure out why the name is not being transferred over. 

There may be several reasons:

  • segue.identifier is not the expected one
  • segue.destination is not of the expected class
  • the name you pass is empty.

You should add several prints at each step of prepare to check for this.

If you want more precise help, you should post the complete code of the class.

Okay I will show the complete code. The error I am getting is the name being transferred is nil. The willSelectRowAt is does not extend the scope of the selectedNameInCell.

class FavouritesVC: UITableViewController {
   

  var currentFav: CurrentPlayers?
   
   
  var selectedNameInCell : String?
   
  var favSet: OrderedSet<CurrentPlayers> {
    FavouriteManager.shared.favSet
  }
   

  override func viewDidLoad() {
    super.viewDidLoad()
    if currentFav == nil {
    //display nil
    self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
    } else {
    NotificationCenter.default.post(name: .passFavNotification,
    object: self.currentFav)
    }
  }
   
  @objc
    func handleFavNotification(notification: Notification) {
      tableView.reloadData()
    }

   

  override func numberOfSections(in tableView: UITableView) -> Int {
     return 1
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return favSet.count
  }
   
   
  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 152
  }
   
   
  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "favcell", for: indexPath) as! FavCell
    let itemFav = favSet[favSet.index(favSet.startIndex, offsetBy: indexPath.row)]
    cell.layer.borderColor = UIColor.black.cgColor
    cell.layer.borderWidth = 0.5
    cell.contentView.backgroundColor = .random

    cell.update(with: itemFav)
    return cell
  }
   
  override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    if let cell = tableView.cellForRow(at: indexPath) as? FavCell {
      selectedNameInCell = cell.name.text
    }
    return indexPath
  }
   
   
   
  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if segue.identifier == "hs" {
        print("this is the segue destination: \(segue.destination)")
        print("name being transferred is \(selectedNameInCell)")
        if let destinationController = segue.destination as? HighlightsVC, let destName = selectedNameInCell {
          destinationController.playerName = destName
         }
      }
    }
   
}
  • Can you show the complete code of FavCell? In addition, can you tell us from where the segue to HighlightsVC is put?

Add a Comment

Okay I can give you the favcell code it's a custom cell, the segue to HighlightsVC is put where the button is.

class FavCell: UITableViewCell {
   
  let imageController = FetchImage()
   
   
  @IBOutlet weak var favImg: UIImageView!
   
  @IBOutlet weak var name: UILabel!
   
  @IBOutlet weak var team: UILabel!
   
  @IBOutlet weak var position: UILabel!
   
   
  @IBOutlet weak var highlights: UIButton!
   
   
  @IBOutlet weak var stats: UIButton!
   

   
  func update(with itemFav: CurrentPlayers) {
    name.text = itemFav.yahooName
    team.text = itemFav.team
    position.text = itemFav.position
    favImg.image = UIImage(named: "Grey")
    let url = URL(string: itemFav.photoUrl!)
    imageController.fetchItemArtwork(url: url!) {
      (image) in
      if let image = image {
        DispatchQueue.main.async {
          self.favImg.image = image
          self.favImg.roundedImage()
        }
  }

}
  }
   
   

  func goToSite() {
    if let url = URL(string: "https://www.hockey-reference.com/") {
    UIApplication.shared.open(url, options: [:])

  }
  }
   


   
   
   
}

Thanks for posting code.

But we need to know:

  • what do you get as result of print (are they fired ?):
            print("this is the segue destination: \(segue.destination)")
            print("name being transferred is \(selectedNameInCell)")
  • how did you define "hs" segue, very precisely:

from where (cell ? VC itself ?)

did you do a clean build folder after removing one of the duplicates ?

  • Could you also add a print :
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        if let cell = tableView.cellForRow(at: indexPath) as? FavCell {
            selectedNameInCell = cell.name.text
            print("selectedNameInCell", selectedNameInCell)
        }
        return indexPath
    }
  • Note that you cannot have a segue from a button altogether with an IBAction. Segue would be executed directly and IBAction not called (that different from having performSegue in IBAction, because in this case, segue is not from button but from VC generally).

Add a Comment

Okay I can give you the favcell code it's a custom cell, the segue to HighlightsVC is put where the button is.

Thanks for showing your code and clarifying.

I'm also counting on this:

I have to get rid of the button action and do a segue with storyboard.

As you are connecting the segue from the button, insisting on using tableView(_:willSelectRowAt:) does not make sense and you can remove it.

Please try the following prepare(for:sender:) and tell us what you get.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "hs" {
            print("this is the segue destination: \(segue.destination)")
            if let button = sender as? UIButton {
                var currentView: UIView = button
                while let parentView = currentView.superview {
                    if let cell = parentView as? FavCell {
                        let selectedNameInCell = cell.name.text
                        print("name being transferred is \(selectedNameInCell)")
                        if let destinationController = segue.destination as? HighlightsVC, let destName = selectedNameInCell {
                            destinationController.playerName = destName
                        }
                        break
                    }
                    currentView = parentView
                }
            } else {
                print("The segue is not from UIButton")
            }
        }
    }