iosswiftuitableviewtableviewdidselectrowatindexpath

TableView inside modal view doesn't detect didselectrowat


I have a tableview within a viewcontroller. The viewcontroller is shown modally. For some reason it is not detecting when I tap a cell.

On storyboard for the tableview, I have selection set to single selection and user interaction is enabled. I also set the delegate and datasource to the tableview in storyboard. Any idea why it is not working?

class RecipeCategoryViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
        
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return meals.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "recipeCell", for: indexPath) as! RecipeCategoryTableViewCell
        cell.setMeal(text: meals[indexPath.row].strMeal)

        return cell
    }
    
    
    @IBOutlet var tableView: UITableView!
        
    var meals = [Meal]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.rowHeight = 300.0
        
        fetchMeals()
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
       if segue.identifier == "showRecipeDetail" {

           let detailViewController = segue.destination
                as! RecipeDetailViewController

           let myIndexPath = self.tableView.indexPathForSelectedRow!
           let row = myIndexPath.row
           detailViewController.recipeName = meals[row].strMeal
        }
    }
    
    func fetchMeals() {
        let url = URL(string: "https://www.themealdb.com/api/json/v1/1/filter.php?c=Dessert")!
        
        let task = URLSession.shared.dataTask(with: url, completionHandler: { [self] (data, response, error) in
            if let error = error {
                print("Error with fetching meals: \(error)")
                
                return
            }
            guard let httpResponse = response as? HTTPURLResponse,
                  (200...299).contains(httpResponse.statusCode) else {
                print("Error with the response, unexpected status code: \(String(describing: response))")
                return
            }
            if let data = data {
                let decodedData = try? JSONDecoder().decode(MealsModel.self, from: data)
                if let unwrappedData = decodedData {
                    meals = unwrappedData.meals
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
            }
        })
        task.resume()
    }
}

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("clicked")
        performSegue(withIdentifier: "showRecipeDetail", sender: nil)
    }
}

extension UIImageView {
    func load(url: URL) {
        DispatchQueue.global().async { [weak self] in
            if let data = try? Data(contentsOf: url) {
                if let image = UIImage(data: data) {
                    DispatchQueue.main.async {
                        self?.image = image
                    }
                }
            }
        }
    }
}

I also have a custom cell for the tableview where I just connect a label and set the text from setMeal

outlets


Solution

  • In your code you set delegate to ViewController not RecipeCategoryViewController

    extension ViewController: UITableViewDelegate {
    

    It has to be

    extension RecipeCategoryViewController: UITableViewDelegate {
       func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          print("clicked")
          performSegue(withIdentifier: "showRecipeDetail", sender: nil)
       }
    }