我想为TableViewCell的子视图(即StackView)设置动画。当我隐藏StackView时,TableViewCell的高度没有更新。谷歌搜索之后,我发现我应该调用tableView.beginUpdates
和tableView.endUpdates
来通知tableView单元中有更改。问题是隐藏动画和更改的tableview不同步。
这是表视图单元格的视图层次结构
内容视图-容器视图(用于卡阴影)-容器堆栈视图-[用于标签和开关的堆栈视图]&[用于StudentView容器的StudentStackView]
如何同步单元格高度并以正确的方式隐藏动画?
这是github仓库:GitHub
答案 0 :(得分:1)
`public func setup(classRoom: ClassRoom, toggleInProcess: @escaping () -> (), toggled: @escaping () -> ()) {
containerStackView.addArrangedSubview(studentStackView)
self.nameLabel.text = classRoom.name
self.activeSwitch.isOn = classRoom.isActive
self.studentStackView.isHidden = !self.activeSwitch.isOn // Let him know his hide/unhide.
for student in classRoom.students {
let studentView = StudentView()
studentView.nameLabel.text = student.name
studentStackView.addArrangedSubview(studentView)
}
activeSwitch.addTarget(self, action: #selector(toggleShowStudents(show:)), for: .valueChanged)
self.toggleInProcess = toggleInProcess
self.toggled = toggled
setupShadow()
}`
` @objc func toggleShowStudents(show: Bool) {
UIView.animate(withDuration: 0.3, animations: {
self.studentStackView.isHidden = !self.activeSwitch.isOn
self.toggleInProcess()
self.containerView.layoutIfNeeded()
}) { _ in
self.toggled()
}
}`
您的studentStackView在函数setup
中分配值时,也知道他的隐藏/取消隐藏状态。
答案 1 :(得分:1)
您正确使用beginUpdates()/endUpdates()
。确保不要将someArrangedSubview.isHidden = true/false
放在动画块中,因为表格视图和堆栈视图将相应地处理动画。当表格视图开始更新操作时,堆栈视图将调整您不会删除的所有已排列子视图的大小,以填充单元格的整个空间(即使您对已排列子视图有高度限制)。就我而言,每次我想通过移除已安排的子视图来折叠单元格时,单元格内容都会跳跃-因此我在希望保持静态*的视图和可折叠视图之间添加了一个虚拟视图。静态视图不会调整大小,虚拟视图将根据需要扩展/折叠。希望这会有所帮助。
*静态,因为我不希望动画时视图移动。
答案 2 :(得分:0)
tableView.beginUpdates
和tableView.endUpdates
是您要修改行数或行的选定状态时应调用的函数。
您应尝试reloadData或reloadrowsatindexpaths,这应注意调整单元格的高度。
最好使用performSelector API进行此操作,以免在cellForRowAt
调用堆栈中引起递归。
答案 3 :(得分:0)
我将其留为评论,但对于任何其他遇到此行为的人,根本原因是UILabel在折叠之前会扩大以填充可见区域。
这可以通过做以下两件事来解决:
通过这两个调整,不是将UILabel扩展为填充可见区域,而是扩展了UIView。从外观上看,这似乎是细胞刚刚坍塌。