UIView 不会在操作后更新新的高度约束

UIView does not update new height constraint after action

我在执行操作后(或者换句话说,点击按钮时)更新 UIView 的高度时遇到问题。 所以基本上我创建了一个名为 "BottleView" 的 UIView class ,其中有另一个视图为瓶子内的 "wave animation" 设置动画。

当百分比增加时,动画视图的高度增加并更新。当百分比下降时,高度下降并更新。

每当它减小时,它会立即更新动画视图的高度。但是当增加高度时,它不会立即更新。为了看到更新后的高度限制,我必须重新启动应用程序。

我是不是漏掉了一步?这是用于视觉目的的 gif 和下面的代码

class BottleView: UIView {

    let liquidView = AnimationView()
    let shapeView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        self.backgroundColor = .blue

        self.shapeView.contentMode = .scaleAspectFit
        self.shapeView.image = UIImage(named: "water-bottle")

        self.addSubview(liquidView)
        self.mask = shapeView

        liquidView.anchor(top: .none, leading: leadingAnchor, bottom: bottomAnchor, trailing: trailingAnchor)

        layoutIfNeeded()

        playWavesAnimation()
        animationObserver()
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        shapeView.frame = self.bounds

        NotificationCenter.default.post(name: NSNotification.Name("refreshWaveForBottle"), object: nil)
    }
}

extension BottleView {

    fileprivate func animationObserver() {
         NotificationCenter.default.addObserver(self, selector: #selector(refreshWaterAnimation), name: NSNotification.Name("refreshWaveForBottle"), object: nil)
     }

    @objc func refreshWaterAnimation() {
        NetworkManager.fetchPercentageAmount { (value) in

            DispatchQueue.main.async {
                if value > 0 && value <= 5 {
                    self.liquidView.constrainHeight(constant: 50)
                    self.liquidView.layoutIfNeeded()
                }

                if value > 5 && value <= 10 {
                    self.liquidView.constrainHeight(constant: 80)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 10 && value <= 15 {
                    self.liquidView.constrainHeight(constant: 100)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 15 && value <= 20 {
                    self.liquidView.constrainHeight(constant: 150)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 20 && value <= 25 {
                    self.liquidView.constrainHeight(constant: 200)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 25 && value <= 30 {
                    self.liquidView.constrainHeight(constant: 250)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 30 && value <= 35 {
                    self.liquidView.constrainHeight(constant: 300)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 35 && value <= 40 {
                    self.liquidView.constrainHeight(constant: 350)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 40 && value <= 45 {
                    self.liquidView.constrainHeight(constant: 400)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 45 && value <= 50 {
                    self.liquidView.constrainHeight(constant: 500)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 50 && value <= 55 {
                    self.liquidView.constrainHeight(constant: 600)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 55 && value <= 60 {
                    self.liquidView.constrainHeight(constant: 700)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 60 && value <= 65 {
                    self.liquidView.constrainHeight(constant: 800)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 65 && value <= 70 {
                    self.liquidView.constrainHeight(constant: 900)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 70 && value <= 75 {
                    self.liquidView.constrainHeight(constant: 1000)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 75 && value <= 80 {
                    self.liquidView.constrainHeight(constant: 1100)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 80 && value <= 85 {
                    self.liquidView.constrainHeight(constant: 1200)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 85 && value <= 90 {
                    self.liquidView.constrainHeight(constant: 1300)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 90 && value <= 95 {
                    self.liquidView.constrainHeight(constant: 1400)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 95 && value <= 98 {
                    self.liquidView.constrainHeight(constant: 1450)
                    self.liquidView.layoutIfNeeded()

                }

                if value > 98 {
                    self.liquidView.constrainHeight(constant: 1800)
                    self.liquidView.layoutIfNeeded()

                }

                if value < 1 {
                    self.liquidView.frame.origin.y = self.bounds.height
                }
            }
        }
    }
}

extension BottleView {

    fileprivate func playWavesAnimation() {
        let waveAnimation = Animation.named(waveJSONFile)
        liquidView.animation = waveAnimation
        liquidView.clipsToBounds = true
        liquidView.animationSpeed = 2.0
        liquidView.respectAnimationFrameRate = false
        liquidView.contentMode = .scaleAspectFill
        liquidView.loopMode = .loop
        liquidView.backgroundBehavior = .pauseAndRestore
        liquidView.play()
      }
}

如果你们想知道 "Constrain Height" 的作用...这是自动布局的辅助方法。

extension UIView {
    func constrainHeight(constant: CGFloat) {
        translatesAutoresizingMaskIntoConstraints = false
        heightAnchor.constraint(equalToConstant: constant).isActive = true
    }
}

您需要删除旧的 1

extension UIView {
    func constrainHeight(constant: CGFloat) {
        constraints.forEach {
           if [=10=].firstAttribute == .height {
                self.removeConstraint([=10=])
           }
        } 

        heightAnchor.constraint(equalToConstant: constant).isActive = true
        superView!.layoutIfNeeded()
    }
}