Search code examples
iosswiftuitableviewfiltersections

iOS - Set numberOfSections in tableView to number of filtered cells (Swift)


I've set up my tableView so it filters based on the value of 2 factors of every child of the array (factor1 and factor2) matching with 2 user inputs (factor1UserInput and factor2UserInput). The problem is- because I have my numberOfSections set to return array.count- it loads ALL the cells, including unpopulated cells, for every child in the array.

So, I'm attempting to set my numberOfSections in my tableView to the number of filtered cells (the cells I'm populating) - unless there is a better way to filter these in order to not load unpopulated cells.

numberOfSections code:

func numberOfSections(in tableView: UITableView) -> Int {
    return array.count
}

tableView code:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ExampleCell", for: indexPath)

    let preview = array[indexPath.section]

// BELOW LINE FILTERS THE DATA

    if preview.factor1 == factor1UserInput && preview.factor2 == factor2UserInput {


// TRYING TO ONLY LOAD THESE CELLS

    print("something matches the filter")


    cell.imageView?.image = UIImage(named: "PlaceholderImage")


    if let imageUrl = preview.imageUrl {
        let url = URL(string: imageUrl)
        URLSession.shared.dataTask(with: url!) { (data, response, error) in

            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async {
                cell.imageView?.image = UIImage(data: data!)

            }

            }.resume()
    }

    } else {

    }
            return cell
}

Solution

  • In your case, you should not use the self.array as the source for the tableView, instead, you should declare a proxy variable and use it as the source, something like:

    var displayArray: [YourClass] {
        return array.filter({ (YourClass) -> Bool in
            return /*Your condition here*/
        })
    }
    

    And then in your table view datasource:

    func numberOfSections(in tableView: UITableView) -> Int {
        return displayArray.count
    }
    

    And then apply the same idea for cellForRowAtIndexPath