I want to animate the subviews of the TableViewCell which is StackView. When I hide the StackView, the TableViewCell height not updating. After googling, I found that I should call tableView.beginUpdates
and tableView.endUpdates
to notify tableView that there is a change in the cell. The problem is the hide animation and the change of tableview not sync.
Here is the view hierarchy for tableview cell
Content view - Container View (for card shadow) - Container Stack View - [Stack View for label and switch] & [StudentStackView for container of StudentView]
How can I sync the cell height and hide animation the correct way?
Here is the github repo: GitHub
You are right in using beginUpdates()/endUpdates()
. Make sure you're not placing the someArrangedSubview.isHidden = true/false
in an animate block since the table view and stack view will handle the animations accordingly. When the table view begins update operations, the stack view will resize any arranged subviews that you aren't removing to fill the entire space of the cell (even if you have height constraints on the arranged subview). In my case, the cell content jumped every time I wanted to collapse a cell via removing an arranged subview--so I added a dummy view between the view I wished to remain static* and the collapsible view. The static view won't resize, and the dummy view will expand/collapse as needed. Hope this helps.
*static in the sense that I didn't want the view to move when animating.
`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()
}
}`
your studentStackView also know his hide/unhide status while assigning values in function setup
.
I left this as a comment but for anyone else experiencing this behavior, the root cause is the UILabel is expanding to fill the visible area before collapsing.
This can be fixed by doing the following 2 things:
With these two adjustments, instead of the UILabel expanding to fill the visible area, the UIView expands instead. Visually, this appears as if the the cell just collapses.
tableView.beginUpdates
and tableView.endUpdates
are functions that should be called when you are about to modify rowcount or selected state of the rows.
You should try reloadData or reloadrowsatindexpaths , that should take care of the cell height adjustment.
You would better do it using performSelector API so as not to cause recursion in cellForRowAt
call stack.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.