iosjsonswiftuitableview

Open URL from API when Button is Pressed in Custom TableViewCell


I want to click a button in a custom xib file and it goes to a link passed in through an API using decodable.

I am able to make the entire row redirect to a link from the API by using:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let item = page!.tradeshows[indexPath.row]

    if let eventURLS = item.url {

    UIApplication.sharedApplication().openURL(eventURLS, options: [:], completionHandler: nil)
    } else {print("link not working")
  }
}

But I don't want to select the entire row, I only want to select the button from the custom .xib file.

I also tried:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) - > UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell",
        for: indexPath) as!EventTableViewCell
    let item = page!.tradeshows[indexPath.row]

    cell.registerButton.addTarget(self, action: #selector(UpcomingEventsViewController.onClickedRegistrationButton(_: )),
        for: .touchUpInside)

    cell.registerButton.tag = indexPath.row

    return cell
}

@objc func onClickedRegistrationButton(_ button: UIButton) {
    let buttonLink = button.tag
}

but I'm not sure how to set the link from the JSON data so that the indexPath is correct using this second approach.


Solution

  • As the action is not directly related to the view controller it's more efficient to pass the URL to the cell and open the URL there. The target / action code is not needed.

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
        let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as! EventTableViewCell
        let item = page!.tradeshows[indexPath.row]
        cell.url = item.url
        return cell
    }
    

    In the cell add a property url and an IBAction for the button

    class EventTableViewCell : UITableViewCell {
    
        var url : URL!
    
        // other properties
    
        @IBAction func pushButton(_ sender : UIButton) {
           UIApplication.shared.open(url) 
        }
    
        // other code
    }
    

    Side note:

    Your first snippet is Swift 2 code. The method will never be called in Swift 3+