繁体   English   中英

如何为隐藏在 UITableViewCell 中的 UIStackView 设置动画?

[英]How to animate UIStackView hiding inside UITableViewCell properly?

我想为 StackView 的 TableViewCell 的子视图设置动画。 当我隐藏 StackView 时,TableViewCell 高度不会更新。 google了之后发现应该调用tableView.beginUpdatestableView.endUpdates来通知tableView单元格有变化。 问题是隐藏动画和 tableview 的变化不同步。

这是 tableview 单元格的视图层次结构

内容视图 - 容器视图(用于卡片阴影) - 容器堆栈视图 - [标签和开关的堆栈视图] & [StudentStackView 用于 StudentView 的容器]

如何以正确的方式同步单元格高度并隐藏动画?

这是 github 存储库: GitHub

应用程序的 Gif: UIStackView 动画与单元格高度不同步

您使用beginUpdates()/endUpdates()是正确的。 确保您没有将someArrangedSubview.isHidden = true/false放在动画块中,因为表视图和堆栈视图将相应地处理动画。 当表视图开始更新操作时,堆栈视图将调整您没有删除的任何排列的子视图的大小以填充单元格的整个空间(即使您对排列的子视图有高度限制)。 就我而言,每次我想通过删除排列的子视图来折叠单元格时,单元格内容都会跳动——所以我在我希望保持静态* 的视图和可折叠视图之间添加了一个虚拟视图。 静态视图不会调整大小,虚拟视图将根据需要展开/折叠。 希望这可以帮助。

*静态,因为我不希望视图在动画时移动。

 `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分配值时也知道他的隐藏/取消隐藏状态。

我将此留作评论,但对于遇到此行为的其他任何人,根本原因是 UILabel 在折叠之前正在扩展以填充可见区域。

这可以通过执行以下两件事来解决:

  1. 在 UILabel 正下方,插入一个空白 UIView
  2. 将 UILabel 的 Content Hugging Priority 调整为“Required”

通过这两个调整,而不是 UILabel 扩展以填充可见区域,而是 UIView 扩展。 从视觉上看,这看起来好像单元格刚刚折叠。

tableView.beginUpdatestableView.endUpdates是当您将要修改行数或行的选定状态时应调用的函数。

您应该尝试 reloadData 或reloadrowsatindexpaths ,它们应该负责单元格高度的调整。

您最好使用 performSelector API 来执行此操作,以免在cellForRowAt调用堆栈中引起递归。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM