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

如何实现点击Cell按钮切换UILabel文本的隐藏/显示(初始显三行)

实现跨Cell的文本展开/收起功能

1. 定义数据模型

先创建模型管理文本内容和展开状态,统一控制显示逻辑:

struct TextItem {
    let content: String
    var isExpanded: Bool = false // 初始为收起状态
}

2. 配置含UILabel的文本Cell

自定义Cell承载长文本Label,根据模型状态设置显示行数:

class TextCell: UITableViewCell {
    static let identifier = "TextCell"
    
    private let contentLabel: UILabel = {
        let label = UILabel()
        label.lineBreakMode = .byTruncatingTail // 收起时显示省略号
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        contentView.addSubview(contentLabel)
        NSLayoutConstraint.activate([
            contentLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
            contentLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            contentLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
            contentLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -16)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configure(with item: TextItem) {
        contentLabel.text = item.content
        // 收起时显示3行,展开时自动换行(设为0)
        contentLabel.numberOfLines = item.isExpanded ? 0 : 3
    }
}

3. 配置按钮Cell

自定义按钮Cell,通过闭包传递点击事件,同步按钮文字状态:

class ButtonCell: UITableViewCell {
    static let identifier = "ButtonCell"
    
    private let toggleButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("展开", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()
    
    var onButtonTap: (() -> Void)?
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        contentView.addSubview(toggleButton)
        NSLayoutConstraint.activate([
            toggleButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
            toggleButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 12),
            toggleButton.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -12)
        ])
        toggleButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc private func buttonTapped() {
        onButtonTap?()
    }
    
    // 根据展开状态更新按钮文字
    func updateButtonTitle(isExpanded: Bool) {
        toggleButton.setTitle(isExpanded ? "收起" : "展开", for: .normal)
    }
}

4. ViewController整合逻辑

在控制器中管理数据源,处理按钮点击事件并刷新对应Cell:

class ViewController: UIViewController {
    private let tableView = UITableView()
    private var textItem = TextItem(content: "替换成你的长文本内容...")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
    }
    
    private func setupTableView() {
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
        
        tableView.register(TextCell.self, forCellReuseIdentifier: TextCell.identifier)
        tableView.register(ButtonCell.self, forCellReuseIdentifier: ButtonCell.identifier)
        
        // 开启自动计算Cell高度,适配展开/收起后的高度变化
        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableView.automaticDimension
        
        tableView.dataSource = self
    }
}

extension ViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2 // 文本Cell + 按钮Cell
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: TextCell.identifier, for: indexPath) as! TextCell
            cell.configure(with: textItem)
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: ButtonCell.identifier, for: indexPath) as! ButtonCell
            cell.updateButtonTitle(isExpanded: textItem.isExpanded)
            cell.onButtonTap = { [weak self] in
                guard let self = self else { return }
                // 切换展开状态
                self.textItem.isExpanded.toggle()
                // 刷新文本Cell和按钮Cell,保证状态同步
                tableView.reloadRows(at: [IndexPath(row: 0, section: 0), indexPath], with: .automatic)
            }
            return cell
        }
    }
}

关键注意点

  • 必须设置Label的lineBreakMode为.byTruncatingTail,收起时才会显示省略号提示用户有更多内容。
  • 开启TableView自动高度计算,避免展开/收起时Cell高度异常。
  • 按钮点击后要同时刷新文本Cell和按钮Cell,确保状态完全同步。

内容的提问来源于stack exchange,提问作者Mikl.hart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:35:11