隐藏/显示多行标签的动画可能会出现问题,尤其是在堆栈视图中使用时。
如果你试一试,你会发现即使在表格视图单元的外部 - 只是视图中的堆栈视图 - 在切换 .isHidden 时你会看到同样的问题标签的属性。这是因为UILabel 垂直居中它的文本。
这是另一种方法,它不使用堆栈视图(背景颜色为清晰起见):
顶部标签设置为 1 行;阅读更多是一个普通按钮,底部标签设置为0行。
您会注意到粉红色的矩形。那是UIView,我将其命名为ShimView - 稍后会详细介绍。
顶部标签被限制Top: 4, Leading: 8, Trailing: 8
按钮受约束Top: 0 (to topLabel), Leading: 8, Trailing: 8
底部标签受约束Top: 0 (to button), Leading: 8, Trailing: 8
“垫片视图”受到限制Trailing: 8, Top: 0 (*to the top of bottom label*), Bottom: 4 (to the contentView)
“shim 视图”也给定了一个高度约束 21,Priority: 999 -- 并且该高度约束连接到单元类中的一个 IBOutlet。 p>
关键是我们将调整 shim 的 Height 约束的 .constant 以展开/折叠单元格。
在初始化时,我们将 .constant 设置为 0 - 这将使底部标签保持在其由内容确定的高度,但不会可见,因为它将被单元格的 contentView 裁剪。
当我们想要“显示/隐藏”标签时,我们将为 shim 的高度 .constant 设置动画。
结果:
还有,清除背景色后的结果:
代码如下:
//
// ExpandCollapseTableViewController.swift
//
// Created by Don Mag on 6/19/18.
//
import UIKit
class ExpandCollapseCell: UITableViewCell {
@IBOutlet var topLabel: UILabel!
@IBOutlet var theButton: UIButton!
@IBOutlet var bottomLabel: UILabel!
@IBOutlet var theShim: UIView!
@IBOutlet var shimHeightConstraint: NSLayoutConstraint!
var myCallBack: (() -> ())?
@IBAction func didTap(_ sender: Any) {
myCallBack?()
}
}
class ExpandCollapseTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 100
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandCollapseCell", for: indexPath) as! ExpandCollapseCell
cell.topLabel.text = "Index Path - \(indexPath)"
cell.bottomLabel.text = "Line 1\nLine 2\nLine 3\nLine 4"
// init to "collapsed"
// in actual use, this would be tracked so the row would remain expanded or collapsed
// on reuse (when the table is scrolled)
cell.shimHeightConstraint.constant = 0
if true {
cell.topLabel.backgroundColor = .clear
cell.theButton.backgroundColor = .clear
cell.bottomLabel.backgroundColor = .clear
cell.theShim.backgroundColor = .clear
}
cell.myCallBack = {
UIView.animate(withDuration: 0.3) { // It must be 0.3
self.tableView.beginUpdates()
cell.shimHeightConstraint.constant = (cell.shimHeightConstraint.constant == 0) ? cell.bottomLabel.frame.size.height : 0
self.tableView.layoutIfNeeded()
self.tableView.endUpdates()
}
}
return cell
}
}