为什么我用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
相关产品推荐
相关产品推荐

