我的 tableView 约束在 ViewController 的顶部、左侧、右侧和底部。
我将 UIButton 放在标题视图中,该标题具有使用插入和删除带有淡入淡出动画的行来扩展和收缩的功能。
但是,当我在第一个和最后一个部分展开而第二个和第三个部分缩小的情况下点击按钮展开第三个部分时,第三个部分的单元格与第三个部分重叠,就像这个视频一样。
我想知道为什么会发生这种情况以及解决方案。
预先感谢。
struct TwoDimentionalData {
let items: [String]
var isExpanded: Bool
}
class ViewController: UIViewController {
let headerId = "headerId"
let cellId = "cellId"
var datas = [TwoDimentionalData]()
@IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
tableView.dataSource = self
tableView.register(CollapsibleTableViewCell.self, forCellReuseIdentifier: cellId)
tableView.register(CopplasibleTableViewHeader.self, forHeaderFooterViewReuseIdentifier: headerId)
}
}
override func viewDidLoad() {
super.viewDidLoad()
datas = [TwoDimentionalData(items: ["Item1-1", "Item1-2"], isExpanded: true),
TwoDimentionalData(items: ["Item2-1", "Item2-2", "Item2-3"], isExpanded: true),
TwoDimentionalData(items: ["Item3-1", "Item3-2", "Item3-3", "Item3-4"], isExpanded: true),
TwoDimentionalData(items: ["Item4-1"], isExpanded: true)
]
}
}
extension ViewController: UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return datas.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return datas[section].isExpanded ? datas[section].items.count : 0
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
cell.backgroundColor = .green
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return datas[indexPath.section].isExpanded ? 50 : 0
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as? CopplasibleTableViewHeader
header?.expandButton.tag = section
header?.collapsibleTableViewHeaderDelegate = self
header?.setLayout()
header?.contentView.backgroundColor = .yellow
return header
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
}
extension ViewController: CollapsibleTableViewHeaderDelegate {
func didTapExpandButton(tag: Int) {
let isExpended = datas[tag].isExpanded
datas[tag].isExpanded = !isExpended
var indexPaths = [IndexPath]()
let items = datas[tag].items
for row in items.indices {
let indexPath = IndexPath(row: row, section: tag)
indexPaths.append(indexPath)
}
tableView.performBatchUpdates {
if isExpended {
tableView.deleteRows(at: indexPaths, with: .fade)
} else {
tableView.insertRows(at: indexPaths, with: .fade)
}
}
}
}
protocol CollapsibleTableViewHeaderDelegate: AnyObject {
func didTapExpandButton(tag: Int)
}
class CopplasibleTableViewHeader: UITableViewHeaderFooterView {
weak var collapsibleTableViewHeaderDelegate: CollapsibleTableViewHeaderDelegate?
lazy var expandButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(systemName: "chevron.down"), for: .normal)
button.addTarget(self, action: #selector(handleExpandButton), for: .touchUpInside)
return button
}()
@objc private func handleExpandButton(button: UIButton) {
print("handleExpandButton")
let tag = button.tag
collapsibleTableViewHeaderDelegate?.didTapExpandButton(tag: tag)
}
override func prepareForReuse() {
super.prepareForReuse()
}
func setLayout() {
addSubview(expandButton)
expandButton.translatesAutoresizingMaskIntoConstraints = false
expandButton.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
expandButton.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
}
}
我通过使用 reloadRows 方法而不是插入/删除行方法解决了这个问题。
首先,将 numberofRowsInSection 更改为以下代码以防止崩溃。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return datas[section].items.count
}
在 CollapsibleTableViewHeaderDelegate 内部,
extension ViewController: CollapsibleTableViewHeaderDelegate {
func didTapExpandButton(tag: Int) {
let isExpended = datas[tag].isExpanded
datas[tag].isExpanded = !isExpended
var indexPaths = [IndexPath]()
let items = datas[tag].items
for row in items.indices {
let indexPath = IndexPath(row: row, section: tag)
indexPaths.append(indexPath)
}
tableView.performBatchUpdates {
tableView.reloadRows(at: indexPaths, with: .fade)
}
}
}
通过这种方式,我不再获得重叠的单元格,但仍然获得淡入淡出动画。