如何实现点击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
相关产品推荐
相关产品推荐

