You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UITableView的cellForRowAt方法未调用,表格显示为空求助

解决UITableView的cellForRowAt未被调用的问题

我来帮你捋捋这个问题,这种情况我之前做iOS开发时也碰到过——明明numberOfRowsInSection返回了正确的行数,但cellForRowAt就是不执行,表格一片空白。大概率是表格自身的布局或者配置出了问题,导致系统觉得没必要去渲染单元格,下面是几个排查和解决的方向:

1. 先检查UITableView的约束与Frame

这是最常见的原因!如果你的tableView约束没设置对,导致它的实际显示尺寸是0(比如高度为0或者宽度为0),系统就不会触发cell的渲染逻辑。

  • 打开storyboard/xib,确认tableView的top、bottom、leading、trailing都和父视图(或者safe area)正确绑定,没有约束冲突或缺失的情况。
  • 可以在viewDidLoad里加一行打印,看看表格的实际frame:
    print("Table frame: \(table.frame)")
    
    如果输出的width或height是0,那肯定是约束的问题,赶紧调整约束让表格能正常显示在屏幕上。

2. 确认行高(rowHeight)设置

如果tableView的行高被设置成了0,哪怕有多少行,cell也不会被渲染出来:

  • 你可以在viewDidLoad里手动设置一个固定行高试试:
    table.rowHeight = 44.0 // iOS常用的单元格高度
    
  • 要是想用自动行高,记得同时设置estimatedRowHeight:
    table.estimatedRowHeight = 44.0
    table.rowHeight = UITableView.automaticDimension
    

3. 确保reloadData在主线程执行

你的getFiles()方法里调用了table.reloadData(),虽然contentsOfDirectory是同步方法,但有时候如果代码逻辑不小心跑到后台线程,刷新表格的操作就会失效。建议把刷新操作包裹在主线程里:

func getFiles() {
    let filemgr = FileManager.default
    guard let path = filemgr.urls(for: .documentDirectory, in: .userDomainMask).last else {
        print("Failed to get document directory path")
        return
    }
    
    do {
        rows = try filemgr.contentsOfDirectory(atPath: path.path)
        print("Got \(rows.count) files")
        // 强制在主线程刷新表格
        DispatchQueue.main.async {
            self.table.reloadData()
        }
    } catch {
        print("Error enumerating files: \(error.localizedDescription)")
    }
}

4. 检查IBOutlet是否正确连接

虽然你声明了@IBOutlet weak var table: UITableView!,但要确认这个outlet确实和storyboard里的表格控件连上了——有时候拖拽连接时可能没成功,导致table是nil。
可以在viewDidLoad开头加个断言来验证:

override func viewDidLoad() {
    super.viewDidLoad()
    // 检查outlet是否连接成功,没连接会直接崩溃提示
    assert(table != nil, "Table view outlet is not connected!")
    
    // 其他初始化代码...
}

调整后的完整代码参考

import UIKit

class BackupViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var rows:[String] = []
    
    @IBOutlet weak var table: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        assert(table != nil, "Table view outlet is not connected properly!")
        
        self.table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        self.table.dataSource = self
        self.table.delegate = self
        
        // 设置固定行高
        self.table.rowHeight = 44.0
        
        getFiles()
    }
    
    func getFiles() {
        let filemgr = FileManager.default
        guard let path = filemgr.urls(for: .documentDirectory, in: .userDomainMask).last else {
            print("Failed to retrieve document directory path")
            return
        }
        
        do {
            rows = try filemgr.contentsOfDirectory(atPath: path.path)
            print("Successfully fetched \(rows.count) files")
            DispatchQueue.main.async {
                self.table.reloadData()
            }
        } catch {
            print("Error while enumerating files: \(error.localizedDescription)")
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Number of rows: \(rows.count)") // 可以加这个打印确认返回值
        return rows.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = self.table.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = rows[indexPath.row]
        return cell
    }
}

先从约束和outlet连接开始排查,这两个是最容易踩坑的点,解决后应该就能正常显示单元格了。

内容的提问来源于stack exchange,提问作者Ginso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:49:16