首页 > 解决方案 > 设置高度动画时阴影/单元格闪烁

问题描述

我的单元格上的阴影有问题(点击 GIF 以查看动画):

在此处输入图像描述

我打电话时阴影闪烁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)

单元格中的动画代码animate如下:

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()
}

并且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()
    }
}

如果我在不调用的情况下执行动画self.tableView.beginUpdates()并且self.tableView.endUpdates()不会发生闪烁,但是单元格高度当然不会相应地调整。我真的不知道如何解决这个问题。所有视图和单元格都有透明背景(只有表格视图背景是纯色)。在每个单元格/视图中clipToBounds关闭viewand 。contentView我也尝试过使用纯色作为背景,但这似乎没有任何区别。我怎样才能解决这个问题?

任何指针将不胜感激!谢谢!

标签: iosswiftuitableview

解决方案


我的回答是从这里得到启发的

我花了 2 天时间才找到答案。最后,我注意到,当我调用tableView.reloadRows(at: [indexPath], with: .fade)或只是简单地tableView.beginUpdates()调用时tableView.endUpdates(),如果在 XCode 中使用 Debug View Hierarchy 暂停视图,由于某些原因clipsToBounds = true,即使我明确地将其设置为false.

对我有用的解决方案是:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.clipsToBounds = false
    cell.layer.masksToBounds = false
    cell.contentView.layer.masksToBounds = false
}

推荐阅读