Dan Ram
Dan Ram

Reputation: 181

What are the reasons for cellForRowAtIndexPath getting called more than once for every row

I have a tableview and I have 20 prototype cells and tableview's Content parameter is Dynamic Prototypes

At a time I show only one protoype cell but for some weird reason cellForRowAtIndexPath is getting called twice.

I have gone through my code and I call reloaddata just once.

I couldn't figure out what could have caused tableview to call cellForRowAtIndexPath twice !

so i generally would like to know what and all could cause tableview to call cellForRowAtIndexPath more than once for the same row

Update:

In one of the prototype cells if a button is clicked then probably I would reload the data so that I can show some other prototype cell but then also its called twice

but still number of rows count is one

Upvotes: 0

Views: 2257

Answers (2)

Milan Nosáľ
Milan Nosáľ

Reputation: 19747

If you call reloadData() explicitly yourself, that would explain it. The tableView loads data by default in UITableViewController, so explicitly calling it again would trigger cellForRowAt the second time. You can easily confirm this by removing an explicit call to reloadData() - then the tableView should look correctly and the cellForRowAt should be called only once.

I tested a following minimal working example in Playgrounds, and it got called only once:

import UIKit
import PlaygroundSupport

class A: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Reload", style: .plain, target: self, action: #selector(buttonPressed))
    }


    @objc func buttonPressed() {
        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(">>>> calling numberOfRowsInSection")
        return 1
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print(">>>> \(indexPath)")
        return UITableViewCell()
    }

}

PlaygroundPage.current.liveView = UINavigationController(rootViewController: A())

So unless you do something else, the cellForRowAt should be called really just once per reloadData().

Upvotes: 3

Shehata Gamal
Shehata Gamal

Reputation: 100503

By default there is a call when view controller is initialized to reload the tableView when you add another one then it's 2

Upvotes: 0

Related Questions