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

Okay so I downloaded a swift package that gives me access to an orderedSet so I can solve that issue but thanks for your suggestion. Anyways I get the cannot find cellForRow error in scope.

   override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    if let cell = cellForRow(at: IndexPath) {
      selectedNameInCell = cell.yahooName
    }
  }

My mistake, just change:

    if let cell = tableView.cellForRow(at: IndexPath) {

Okay I have a new error this time. Cannot convert value of type 'IndexPath.Type' to expected argument type 'IndexPath'

override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    if let cell = tableView.cellForRow(at: IndexPath) {
      selectedNameInCell = cell.yahooName
    }
  }

Just a typo, working in forum editor and not XCode: it is indexPath and not IndexPath

    if let cell = tableView.cellForRow(at: indexPath) {

okay thanks but I get the error Value of type 'UITableViewCell' has no member 'yahooName'. I should show my cellForRowAt. I can also access yahooName with currentFav.yahooName but not sure how to access from the cell.

   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
  }

I don't know enough about cell. Is it a custom class ? Or is yahooName the title of the standard cell ? In such a case, just call:

selectedNameInCell = cell.textLabel!.text!

I have a custom cell actually. I have the function I used to display it at the bottom. I am curious with willRowAt do I return indexPath?


   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()
    }
   }
 }
}

So you should:

    if let cell = tableView.cellForRow(at: IndexPath) as? FavCell {
      selectedNameInCell = cell.name.text
    }

To be sure to understand where you stand now, could you repost the most recent code:

  • IBAction
  • prepare for segue

Another option is to get the name directly in the IBAction:

@IBAction func CamButtonA(_ sender: UIButton) {

     // Find the cell which contains this button
    var superview = sender.superview
    while let view = superview, !(view is UITableViewCell) {
        superview = view.superview
    }
    guard let cell = superview as? FavCell else {
        return
    }
    selectedNameInCell = cell.name.text
    performSegue(withIdentifier: "hs", sender: nil) 
}

Okay I get the same error unrecognized selector sent to instance '0x7fd4c4098200'. I tried both ways but end up with the same error. You don't but the button in the cell?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if segue.identifier == "hs" {
        if let destinationController = segue.destination as? HighlightsVC, let destName = selectedNameInCell {
          destinationController.playerName = destName
         }
      }
    }
   
   
   
  override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    if let cell = tableView.cellForRow(at: indexPath) as? FavCell {
      selectedNameInCell = cell.name.text
    }
    return indexPath
  }
   
  @IBAction func CamButtonA(_ sender: UIButton) {
    performSegue(withIdentifier: "hs", sender: nil)
  }
  • Where do you get the error ?

Add a Comment

The error comes from my camButtonA. Unrecognized selector

   @IBAction func CamButtonA(_ sender: UIButton) {
    performSegue(withIdentifier: "hs", sender: nil)
  }

Check the connection from button in IB to the IBAction. In fact, remove the connection and rebuild.

Note that the name of func should start with lowercase camButtonA.

Okay I have it working but it goes to the vc twice and it also does not transfer the name.

override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    if let cell = tableView.cellForRow(at: indexPath) as? FavCell {
      selectedNameInCell = cell.name.text
      print("destName is \(String(describing: selectedNameInCell))") //does not print name
    }
    return indexPath
  }
  • What do you mean "it goes to VC twice" ? We definetely need more comprehensive code to fully understand what's happening.

Add a Comment

By twice I mean the VC that I go to calls the API twice.

override func viewDidLoad() {
    super.viewDidLoad()
    fetchYoutubeData {
      self.tableView.reloadData()
    } 
  }
  • OK, but I'm sorry to repeat, we need more comprehensive code to fully understand what's happening.

Add a Comment

Okay I will give you more detail I have a function that retrieves youtube data but it is called twice.

   func fetchYoutubeData(completion: @escaping () -> ()) {
     
    let API_Key = "key"
     
    let theName = playerName
    print("this is the player name that was transferred \(playerName)")
     
    let query: [String: String] = ["part" : "snippet", "maxResults" : "5", "q" : theName + "nhl player highlights", "type" : "video", "key" : API_Key]
     
    let baseURL = URL(string: "https://www.googleapis.com/youtube/v3/search")!
    let url = baseURL.withQueries(query)!
    print(url)
     
    URLSession.shared.dataTask(with: url) { (data, response, error) in
       
      guard let data = data else { return }
       
      DispatchQueue.main.async {
         
         
        do {
           
           
          let youtube = try JSONDecoder().decode(Highlights.self, from: data)
          self.youtubeArr = youtube.items
          self.tableView.reloadData()
           
           
        } catch let jsonErr {
          print("Error serializing json:", jsonErr)
        }
      }
       
       
    }.resume()

    
  }
  • Do you confirm that you get         "this is the player name that was transferred (playerName)"       printed twice ? So the key is to analyse WHO calls it. The called function cannot tell us.

Add a Comment