情况是这样的。 stackView 中的标题标签、“阅读更多”按钮和内容标签。而stackView在一个cell中,设置Auto-Layout。 tableView 的单元格的高度设置为 AutoDimension。当我点击按钮时,内容标签将显示或隐藏。
按钮的 Action 方法是
@IBAction func readMore(_ sender: Any) {
tableView.performBatchUpdates({
self.contentLabel.isHidden.toggle()
}, completion: nil)
}
这是慢速动画的结果:
可以看到,当要显示内容时,第2行最先显示,即内容从中心显示。当内容要隐藏时,内容标签立即隐藏,按钮被拉伸(stretch)到内容标签隐藏前的框架。这个动画很奇怪。
此外,如果我将 stackView 的间距设置为 10,情况会变得更糟。标题标签也受到影响:
我调整了一切,stackView 的分布,三个 subview 的内容模式和内容拥抱/压缩优先级。我找不到合适的方法来修复它。
这是理想的结果:
我通过一个小技巧实现了它:
@IBAction func readMore(_ sender: Any) {
tableView.performBatchUpdates({
UIView.animate(withDuration: 0.3) { // It must be 0.3
self.contentLabel.isHidden.toggle()
}
}, completion: nil)
}
我不确定这是最合适的修复方法。所以我想知道为什么会出现这种奇怪的动画,以及是否有更合适的方法来修复它。谢谢!
最佳答案
隐藏/显示多行标签的动画可能会出现问题,特别是在堆栈 View 中使用时。
如果您尝试一下,您会发现即使在 TableView 单元格的外部 - 只是 View 中的堆栈 View - 在切换 时您也会看到同样的问题.isHidden
标签的属性。这是因为 UILabel
垂直居中它的文本。
这是另一种方法,它不使用堆栈 View (为清楚起见使用背景颜色):
Top Label设置为1行; Read More 是一个普通按钮,Bottom Label 设置为 0 行。
您会注意到粉红色的矩形。这是一个 UIView
,我将其命名为 ShimView
- 稍后会详细介绍。
顶部标签受到限制 顶部:4,前导:8,尾随:8
按钮受约束 Top:0(到 topLabel),Leading:8,Trailing:8
底部标签受到限制 Top: 0 (to button), Leading: 8, Trailing: 8
“垫片 View ”受到限制 尾随:8,顶部:0(*到底部标签的顶部*),底部:4(到 contentView)
“垫片 View ”也给定了 21
的高度约束,优先级:999
-- 并且该高度约束已连接到单元格类中的 IBOutlet
。
关键是我们将调整 shim 的高度约束的 .constant
以展开/折叠单元格。
在初始化时,我们将 .constant
设置为 0
- 这将使 Bottom Label 保持在其内容确定的高度,但不会可见,因为它会被单元格的 contentView 裁剪。
当我们想要“显示/隐藏”标签时,我们将为垫片的高度 .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
}
}
关于ios - 在 Cell 的 UIStackView 中隐藏 subview 时动画很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50930254/