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

如何通过代码实现带自定义UITableViewCell子类的UITableView?

纯代码实现自定义UITableViewCell(带图片+标签)并复用的完整方案

没问题,我来给你一步步拆解纯代码实现自定义UITableViewCell并复用的方案,完全贴合你的需求:

1. 先创建自定义UITableViewCell子类

我们直接在代码里定义带图片和标签的cell,所有子视图的创建、布局都写在这个类里,不需要依赖Storyboard原型。

import UIKit

class MyTableViewCell: UITableViewCell {
    // 自定义的图片视图
    let iconImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        imageView.clipsToBounds = true
        imageView.translatesAutoresizingMaskIntoConstraints = false // 关闭自动转换约束,开启AutoLayout
        return imageView
    }()
    
    // 自定义的文本标签
    let titleLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 16)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    // 初始化方法——注册cell时,tableView会自动调用这个方法创建cell实例
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupSubviews() // 初始化时就布局子视图
    }
    
    // 纯代码实现不需要实现这个方法,直接抛错即可
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 封装子视图布局逻辑
    private func setupSubviews() {
        // *注意:必须把自定义子视图添加到cell的contentView,而不是cell本身*
        // 因为contentView是cell负责显示内容的区域,不受选中、高亮等状态的frame影响
        contentView.addSubview(iconImageView)
        contentView.addSubview(titleLabel)
        
        // 用AutoLayout设置约束,确保在不同屏幕上都能正确布局
        NSLayoutConstraint.activate([
            // 图片:左边距16,垂直居中,宽高40
            iconImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            iconImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            iconImageView.widthAnchor.constraint(equalToConstant: 40),
            iconImageView.heightAnchor.constraint(equalToConstant: 40),
            
            // 标签:左边距图片12,右边距16,垂直居中,高度至少20(避免文字被截断)
            titleLabel.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, constant: 12),
            titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
            titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            titleLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 20)
        ])
    }
    
    // 封装数据配置方法,让控制器代码更简洁
    func configure(with icon: UIImage?, title: String) {
        iconImageView.image = icon
        titleLabel.text = title
    }
}

2. 在ViewController中注册并复用Cell

接下来在控制器里注册这个自定义cell,然后通过dequeueReusableCell()实现复用,完全符合你“一次性加载+复用”的需求:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let tableView = UITableView()
    // 模拟数据源,你可以替换成自己的业务数据
    let dataSource: [(icon: UIImage?, title: String)] = [
        (UIImage(systemName: "star.fill"), "我的收藏"),
        (UIImage(systemName: "message.fill"), "消息通知"),
        (UIImage(systemName: "person.fill"), "个人中心")
    ]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
    }
    
    private func setupTableView() {
        // 设置tableView的frame并添加到当前视图
        tableView.frame = view.bounds
        tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(tableView)
        
        // 关键步骤:注册自定义cell类,告诉tableView需要创建哪个类的cell实例
        tableView.register(MyTableViewCell.self, forCellReuseIdentifier: "MyCell")
        
        // 设置数据源和代理
        tableView.dataSource = self
        tableView.delegate = self
        
        // 设置cell高度:这里用自动高度,也可以设固定值比如60
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 60
    }
    
    // MARK: - UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 复用cell:从复用队列中取出可用的cell,没有的话会自动创建(因为我们注册了类)
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyTableViewCell
        // 给cell配置对应的数据
        let item = dataSource[indexPath.row]
        cell.configure(with: item.icon, title: item.title)
        return cell
    }
}

关于你的疑问解答

你提到“注册后无需使用(原文缺失),但不使用该方式时,如何为UITableViewCell的视图添加子视图?”——其实注册cell之后,tableView在需要新cell时,会自动调用我们自定义cell的init(style:reuseIdentifier:)方法创建实例,所以我们把添加子视图、布局约束的逻辑放在这个初始化方法里就完全可以了,不需要依赖Storyboard的原型cell,纯代码就能搞定。

这样既满足了注册cell实现复用的需求,又能完全自定义cell的内容布局。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:39:34