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

为什么我用Swift纯代码编写的MVVM项目中UITableView无法填充数据?

问题修复方案

你遇到的UITableView显示空单元格问题,由以下可修复的错误导致:

1. 自定义Cell未添加子视图与布局约束

你在EmployeeTableViewCell中定义了两个UILabel,但没有将其添加到cell的contentView上,也没有设置布局约束,就算文本赋值成功也不会显示。
替换原EmployeeTableViewCell实现即可修复:

import Foundation
import UIKit

class EmployeeTableViewCell: UITableViewCell{
    
    var employeeIdLabel = UILabel()
    var employeeNameLabel = UILabel()
    
    var employee: EmployeeData?{
        didSet{
            employeeIdLabel.text = String(describing: employee?.id)
            employeeNameLabel.text = employee?.employeeName
        }
    }
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupViews() {
        // 把标签添加到cell的contentView上
        contentView.addSubview(employeeIdLabel)
        contentView.addSubview(employeeNameLabel)
        
        // 关闭自动转换约束
        employeeIdLabel.translatesAutoresizingMaskIntoConstraints = false
        employeeNameLabel.translatesAutoresizingMaskIntoConstraints = false
        
        // 添加布局约束
        NSLayoutConstraint.activate([
            employeeIdLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            employeeIdLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            employeeIdLabel.widthAnchor.constraint(equalToConstant: 50),
            
            employeeNameLabel.leadingAnchor.constraint(equalTo: employeeIdLabel.trailingAnchor, constant: 16),
            employeeNameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            employeeNameLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16)
        ])
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
    
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

2. TableView被自定义导航栏遮挡

你已经将HomeViewController嵌入了UINavigationController,系统会自动提供导航栏,你额外添加的自定义导航栏会遮挡下方的TableView,两种修复方案二选一:

  • 方案一:直接删除configure方法中所有自定义UINavigationBar的相关代码,使用系统自带导航栏即可,原TableView的frame保持0坐标也不会被遮挡。
  • 方案二:保留自定义导航栏,调整TableView的frame避开导航栏、状态栏、底部tabBar的高度,替换原frame设置代码:
let statusBarHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
let navigationBarHeight: CGFloat = 44
let topOffset = statusBarHeight + navigationBarHeight
let tabBarHeight = self.tabBarController?.tabBar.frame.height ?? 0
employeeTableView.frame = CGRect(x: 0, y: topOffset, width: screenWidth, height: screenHeight - topOffset - tabBarHeight)

3. 网络数据回调未切主线程赋值

网络请求的回调默认在后台子线程,直接在子线程给empData赋值触发UI更新会有异常,需要切到主线程操作,修复EmployeeViewModel的callFuncToGetEmpData方法:

func callFuncToGetEmpData(){
    self.apiService.apiToGetEmployeeData{(empData) in
        DispatchQueue.main.async {
            self.empData = empData
        }
    }
}

4. HTTP接口权限配置(未配置时需要添加)

iOS默认禁止HTTP协议请求,你使用的接口是HTTP协议,需要在Info.plist中添加权限配置:右键Info.plist -> Open As -> Source Code,添加以下代码到dict标签内:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:18:03