Search code examples
iosswiftxcodetableviewcell

How to not show tableView until all cell data is finished loading in Swift


I have a tableView but when it loads the cells it looks ugly because the images take a second or two to load in. I have a loader that I want to display and then when all the cells have loaded in I want to show the tableView and hide loader. How can I tell when the tableView is finished loading and show the tableView?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell",
                                                 for: indexPath) as! MainTableViewCell
    let payment = self.payments[indexPath.row]
            if let profileImageUrl = payment.picture {
                cell.profilePicture.loadImageUsingCacheWithUrlString(profileImageUrl)
                cell.profilePicture.layer.cornerRadius = cell.profilePicture.frame.size.width / 2
                cell.profilePicture.clipsToBounds = true
            }

    if payment.message == "none" {
        cell.detailsLabel.text = "No Message"
    } else {
        cell.detailsLabel.text = "\"\(payment.message ?? "")\""
    }

        cell.amountLabel.textColor = UIColor.init(red: 105/255, green: 105/255, blue: 105/255, alpha: 1)
        cell.amountLabel.text = "$\(payment.amount ?? "")"
          
        return cell
    }

Solution

  • So basically you want to show Activity Indicator to warn/show your user to wait for a while until visible cells get loaded properly, correct?

    You have your custom loader (Activity Indicator) that you want to display after all the cells have loaded in as you wrote.

    One thing which is important to understand here is that UITableView is not gonna load all cells because it doesn't work that way.

    No matter how many items you have, the table view will only use tableView:cellForRowAtIndexPath: to create 6 or 7 cells (depends) that are visible.

    If a user scrolls, then the method above will be called again for new visible cells.

    So this means that

    the table never really finishes loading.

    Answering the question on how to detect if the table finished loading visible cells, then you may try this piece of code:

    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            if let lastVisibleIndexPath = tableView.indexPathsForVisibleRows?.last {
                    if indexPath == lastVisibleIndexPath {
                        // turn off/hide your loader
                    }
            }
        }