I am having an issue with the shadow on my cells (tap GIF to see animation):

The shadow flickers when I call beginUpdates:
cell.tappedParentView
.subscribe(onNext: { [weak self] in
guard let self = self else { return }
cell.animate()
self.tableView.beginUpdates()
self.tableView.endUpdates()
self.expandedIndexPaths[indexPath] = !self.expandedIndexPaths[indexPath].or(false)
})
.disposed(by: cell.cellBag)
The animation code animate in the cell is as follows:
func animate() {
spacerViewHeightConstraint?.constant = isExpanded ? 0.0 : 8.0
parentView.updateLayout(isExpanded: !self.isExpanded)
UIView.animate(withDuration: 0.2) {
self.childViews.forEach {
$0.isHidden = self.isExpanded
$0.alpha = self.isExpanded ? 0.0 : 1.0
}
self.layoutIfNeeded()
}
isExpanded.toggle()
}
And updateLayout:
func updateLayout(isExpanded: Bool, animated: Bool = true) {
stackViewLeadingConstraint.constant = isExpanded ? 8.0 : 16.0
stackViewTrailingConstraint.constant = isExpanded ? 8.0 : 16.0
stackViewTopConstraint.constant = isExpanded ? 8.0 : 16.0
stackViewBottomConstraint.constant = isExpanded ? 0.0 : 16.0
let layout = {
self.layoutIfNeeded()
self.shadow = isExpanded ? nil : .card
self.backgroundImageView.alpha = isExpanded ? 0.0 : 1.0
self.containerView.backgroundColor = isExpanded ? .clear : .red
self.titleLabel.textColor = isExpanded ? Theme.text100 : .white
self.descLabel.textColor = isExpanded ? Theme.text100 : .white
self.startingLabel.alpha = isExpanded ? 0.0 : 1.0
self.startingLabel.isHidden = isExpanded
self.priceLabel.alpha = isExpanded ? 0.0 : 1.0
self.priceLabel.isHidden = isExpanded
self.showLessButton.isHidden = !isExpanded
self.showLessButton.alpha = isExpanded ? 1.0 : 0.0
self.stackView.spacing = isExpanded ? 8.0 : 4.0
}
if animated {
UIView.animate(withDuration: 0.2) { layout() }
} else {
layout()
}
}
If I perform the animation without calling self.tableView.beginUpdates() and self.tableView.endUpdates() the flicker doesn't happen but then of course the cell height does not adjust accordingly. I'm really not sure how to fix this. All the views and cells have transparent backgrounds (only the table view background is a solid color). clipToBounds is off for the view and contentView in each cell/view. I have also tried using solid colors as the backgrounds but this doesn't seem to make any difference. How can I fix this?
Any pointers would be greatly appreciated! Thanks!
My answer is inspired from this one here
It took me 2 days to find the answer. Finally, I noticed that when I was calling tableView.reloadRows(at: [indexPath], with: .fade) or just simply tableView.beginUpdates() and tableView.endUpdates() and if pausing the view with the Debug View Hierarchy in XCode, for some reasons the cell had its clipsToBounds = true during the reloading process only, even if I explicitly set it to false.
The solution which worked for me is this:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.clipsToBounds = false
cell.layer.masksToBounds = false
cell.contentView.layer.masksToBounds = false
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With