如何在先前转换的UIView上正确设置变换动画

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (47)

问题摘要

无法在已翻译的情况下正确执行移动和缩放动画UIView

当视图没有被预先移动时,为了获得期望的结果,我首先应用比例然后应用翻译。我使用以下方法为生成的变换设置动画UIViewPropertyAnimator:视图向上或向下缩放,同时相应地移动。

但是,如果在应用此动画变换之前视图已从其原始位置移动(平移),则无法在将View从新位置移动时实现向上或向下缩放的结果。

¡ 虽然转换问题已有详细记录 - 我在提交问题之前已经完成了尽职调查 - 到目前为止我找不到成功的解决方案

转换动画代码

为了便于理解和解决问题,简化了守则。

extension UIView {

   func zoomAndMove(vector: CGPoint, scale: CGPoint){
      self.transform = self.transform.concatenating(CGAffineTransform(scaleX: scale.x, y: scale.y).concatenating(CGAffineTransform(translationX: vector.x, y: vector.y))
   }


   func animateZoomAndMove(from origin: CGPoint, for duration: TimeInterval, cameraZoom: CGPoint, timingFunction: UITimingCurveProvider, controlPoint2: CGPoint(x: 0.8, y: 0.7)) autoplay: Bool = false) -> UIViewPropertyAnimator {
      let animator = UIViewPropertyAnimator(duration: duration, timingParameters: timingFunction)
      let vector = CGPoint(x: self.frame.midX - origin.x, y: self.frame.midY - origin.y)

      animator.addAnimations {
         self.zoomAndMove(vector: vector, scale: cameraZoom)
      }

      if autoplay { animator.startAnimation()}
      return animator
   }
}

到目前为止的尝试

我试图修改我的代码以返回一个转换,该转换在zoomAndMove发生之前考虑先前的转换:

extension UIView {

   func zoomAndMove(vector: CGPoint, scale: CGPoint){

      if self.transform == CGAffineTransform.identity {
          self.transform = self.transform.concatenating(CGAffineTransform(scaleX: scale.x, y: scale.y).concatenating(CGAffineTransform(translationX: vector.x, y: vector.y)) 
      } else {
          let preTransform = self.transform
          self.transform = CGAffineTransform(a: scale.x, b: 0, c: 0, d: scale.y, tx: vector.x + preTransform.tx, ty: vector.y + preTransform.ty)
      }
   }

此代码不会产生所需的效果:视图跳转到新位置,正确缩放并“随机”移动。

我肯定错过了一些东西 - 我可能是针对错误的最终结果矩阵 - 但总而言之,我目前陷入困境。

任何人都应该知道如何执行如此简单的任务,如从已经翻译的UIView中缩放和移动UIView,我将非常感谢他们的输入!

提问于
用户回答回答于

我认为你的变换应该是T * R * ST翻译在哪里,R是旋转,S是规模。所以你的操作顺序应该是这样的,

view.transform = T * R * S * view.transform

所以,你的扩展看起来像,

extension UIView {

    func zoomAndMove(vector: CGPoint, scale: CGPoint) {
        let translationTransform = CGAffineTransform(translationX: vector.x, y: vector.y)
        let scaleTransform = CGAffineTransform(scaleX: scale.x, y: scale.y)

        let combined = translationTransform.concatenating(scaleTransform.concatenating(transform))
        transform = combined
    }
}

扫码关注云+社区

领取腾讯云代金券