每次重载后UITableViewCell文本闪烁消失,非主线程重载不调用cellForRowAt
Hey there, let's break down and fix the two UITableView problems you're running into:
1. Text flashes then disappears after calling reloadData()
What's causing it
Right now, in your cellForRowAt method, you're creating a brand new UITableViewCell every time a cell needs to be displayed—you're not using UITableView's built-in cell reuse system. This leads to inefficient cell management, and when reloadData() runs, old cells get discarded immediately while new ones spin up, causing that jarring flash effect. Additionally, since you're not registering your reuse identifier upfront, the tableView can't properly manage cell caching, which might lead to unexpected behavior like text vanishing entirely.
How to fix it
- Register your cell reuse identifier with the tableView before any data reloads happen.
- Use
dequeueReusableCell(withIdentifier:for:)to fetch reusable cells instead of initializing new ones each time—this is UITableView's intended workflow.
2. reloadData() doesn't trigger cellForRowAt when called off the main thread
What's causing it
UIKit is strictly tied to the main thread—all UI-related operations must run on the main thread to work correctly. When you call reloadData() on a background thread, the tableView can't communicate with its data source/delegate properly, so it never triggers the cellForRowAt method. This is a non-negotiable rule for iOS UI development to ensure thread safety and consistent UI updates.
How to fix it
You're already doing this correctly in your Open method with OperationQueue.main.addOperation, but just remember: any future tableView updates (like inserting rows, updating cell content, or reloading) must also be wrapped in a main thread execution block (either OperationQueue.main or DispatchQueue.main.async).
Modified Working Code
class UtilitySwitcher: NSObject, UITableViewDataSource, UITableViewDelegate { let utilityTableview = UITableView() func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // Handle row selection logic here if needed } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 3 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Dequeue reusable cell instead of creating new instances every time let cell = tableView.dequeueReusableCell(withIdentifier: "Mycell", for: indexPath) cell.textLabel?.text = "hello" return cell } func Open(loginID: String, view: UIView) { let frm = view.bounds let backView = UIView(frame: frm) utilityTableview.frame = CGRect(x: frm.minX + 10, y: frm.midY - 50, width: frm.width - 20, height: 100) utilityTableview.backgroundColor = .white utilityTableview.delegate = self utilityTableview.dataSource = self // Register the cell reuse identifier once during setup utilityTableview.register(UITableViewCell.self, forCellReuseIdentifier: "Mycell") backView.addSubview(utilityTableview) view.addSubview(backView) // Keep reload operations on the main thread (you had this right!) OperationQueue.main.addOperation { self.utilityTableview.reloadData() } } }
A couple quick extra notes:
- Fixed the typo in your class name (
UtititySwitcher→UtilitySwitcher) for consistency. - Registering the cell once during tableView setup is enough—no need to repeat it on every reload.
dequeueReusableCell(withIdentifier:for:)automatically creates a new cell if none are available in the reuse pool, so you don't have to handle that edge case manually.
内容的提问来源于stack exchange,提问作者Amritpal

