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

时间:2018-06-26 09:11:55

标签: ios swift uitableview uistackview

我想为TableViewCell的子视图(即StackView)设置动画。当我隐藏StackView时,TableViewCell的高度没有更新。谷歌搜索之后,我发现我应该调用tableView.beginUpdatestableView.endUpdates来通知tableView单元中有更改。问题是隐藏动画和更改的tableview不同步。

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

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

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

这是github仓库:GitHub

应用的Gif: UIStackView animated not sync with cell height

4 个答案:

答案 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.beginUpdatestableView.endUpdates是您要修改行数或行的选定状态时应调用的函数。

您应尝试reloadData或reloadrowsatindexpaths,这应注意调整单元格的高度。

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

答案 3 :(得分:0)

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

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

  1. 在UILabel的正下方,插入一个空白的UIView
  2. 将UILabel的内容拥抱优先级调整为“必需”

通过这两个调整,不是将UILabel扩展为填充可见区域,而是扩展了UIView。从外观上看,这似乎是细胞刚刚坍塌。