【问题标题】:Swift animation chaining using CGAffineTransforms使用 CGAffineTransforms 的 Swift 动画链接
【发布时间】:2019-01-10 22:42:22
【问题描述】:

我正在尝试为我的应用创建背景动画。我想要实现的部分目标是:

1) 图像(从数组中选择的随机颜色/形状)随机出现在视图上。 2)然后它的大小迅速增长(从不可见,到可见)。 3)然后将在给定方向缓慢移动,同时旋转,持续 10 秒。 4)然后它将缩小到不可见的大小并从视图中删除。

我发现形状将在步骤 1 和步骤 2 中正确显示。然后,形状将在动画/步骤 3 开始时跳转到屏幕上的随机位置(以下代码中的转换 3)。当它移动时,它的大小也会减小。然后对于第 4 步,它会跳回到第 1 步和第 2 步中的原始位置,然后按预期缩小屏幕。

我终其一生都无法弄清楚这里发生了什么。我希望我没有错过一些令人尴尬的显而易见的事情。

提前感谢您的帮助!

class BackgroundAnimation {

func animation(animationView: UIView) {

    let colourArray = [
    UIColor(red:0.99, green:0.80, blue:0.05, alpha:1.0),
    UIColor(red:0.06, green:0.22, blue:0.29, alpha:1.0),
    UIColor(red:0.95, green:0.18, blue:0.30, alpha:1.0),
    UIColor(red:0.35, green:0.77, blue:0.92, alpha:1.0),
    UIColor(red:0.95, green:0.61, blue:0.19, alpha:1.0)
    ]

    let imageArray = [
    "Cross",
    "Circle",
    "Halfmoon",
    "Square",
    "Triangle"
    ]

    //Animation constants
    let initialDimensions = 10
    let pathLength: CGFloat = 100
    let pathDuration = 10
    let scaleFactor: CGFloat = 5
    let scaleDuration = 1

    //Select the random image and random colour that is to be animated.
    let image = UIImage(named: imageArray[Int.random(in: 0...imageArray.count - 1)])
    let imageView = UIImageView(image: image)


    imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
    imageView.tintColor = colourArray[Int.random(in: 0...colourArray.count - 1)]
    imageView.contentMode = .scaleAspectFit
    imageView.frame = CGRect(x: 0, y: 0, width: initialDimensions, height: initialDimensions)
    animationView.insertSubview(imageView, at: 0)

    //create a random start location and angle of direction
    let startPointX = CGFloat.random(in: 0...animationView.frame.width)
    let startPointY = CGFloat.random(in: 0...animationView.frame.height)
    let pathAngle = CGFloat.random(in: 0...(CGFloat.pi * 2))
    imageView.center = CGPoint(x: startPointX, y: startPointY)

    //Calculate the endpoint from path angle and length
    let translationX = pathLength * sin(pathAngle)
    let tanslationY = -(pathLength * cos(pathAngle))


    //Define the transitions for the aniamtion
    var transition1 = CGAffineTransform.identity
    transition1 = transition1.scaledBy(x: scaleFactor, y: scaleFactor)


    var transition2 = CGAffineTransform.identity
    transition2 = transition2.translatedBy(x: translationX, y: tanslationY)
    transition2 = transition2.rotated(by: CGFloat.random(in: CGFloat.pi * 1/4 ... CGFloat.pi * 3/4))


    var transition3 = CGAffineTransform.identity
    transition3 = transition3.scaledBy(x: 0.001, y: 0.001)




    UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0, options: .beginFromCurrentState, animations: {

        imageView.transform = transition1

    }, completion: {finished in

        UIView.animate(withDuration: TimeInterval(pathDuration), delay: 0, options: .beginFromCurrentState, animations: {

            imageView.transform = transition2

        }, completion: { finished in

            UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0, options: .beginFromCurrentState, animations: {

                imageView.transform = transition3

            }, completion: { finished in

                imageView.removeFromSuperview()

            })

        })

    })

}

}

【问题讨论】:

    标签: swift animation cgaffinetransform


    【解决方案1】:

    用 imageView.center 或 imageView.frame.origin 改变你的位置

    imageView.frame.origin = CGPoint(x: translationX, y: tanslationY)
    

    但你应该计算目的地,然后将 frame.origin 设置为目的地

    【讨论】:

    • 非常感谢您回复我!我已经实现了更改,现在当我计算 endPointx 和 endPointY 时,运动可以工作了。但是,当我尝试使用 var transition2 = CGAffineTransform.identity transition2 = transition2.rotated(by: CGFloat.random(in: CGFloat.pi * 1/4 ... CGFloat.pi * 3/4)) imageView.frame.origin = CGPoint(x: endPointX, y: endPointY) imageView.transform = transition2 应用旋转时,对象会旋转,但随着它移动到目的地也会变小。你知道这是为什么吗?
    • 评论太长,我将在另一个答案中显示代码。谢谢!
    【解决方案2】:

    参考 Ehsan 的有用回复:

    这已经解决了移动问题,但是当我尝试在第二个动画块中应用旋转时,imageView 变得越来越小。更新代码如下:

    class BackgroundAnimation {
    
    func animation(animationView: UIView) {
    
        let colourArray = [
        UIColor(red:0.99, green:0.80, blue:0.05, alpha:1.0),
        UIColor(red:0.06, green:0.22, blue:0.29, alpha:1.0),
        UIColor(red:0.95, green:0.18, blue:0.30, alpha:1.0),
        UIColor(red:0.35, green:0.77, blue:0.92, alpha:1.0),
        UIColor(red:0.95, green:0.61, blue:0.19, alpha:1.0)
        ]
    
        let imageArray = [
        "Cross",
        "Circle",
        "Halfmoon",
        "Square",
        "Triangle"
        ]
    
        //Animation constants
        let initialDimensions = 10
        let pathLength: CGFloat = 100
        let pathDuration = 10
        let scaleFactor: CGFloat = 3
        let scaleDuration = 1
    
        //Select the random image and random colour that is to be animated.
        let image = UIImage(named: imageArray[Int.random(in: 0...imageArray.count - 1)])
        let imageView = UIImageView(image: image)
    
    
        imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
        imageView.tintColor = colourArray[Int.random(in: 0...colourArray.count - 1)]
        imageView.contentMode = .scaleAspectFit
        imageView.frame = CGRect(x: 0, y: 0, width: initialDimensions, height: initialDimensions)
        animationView.insertSubview(imageView, at: 0)
    
        //create a random start location and angle of direction
        let startPointX = CGFloat.random(in: 0...animationView.frame.width * 0.9)
        let startPointY = CGFloat.random(in: 0...animationView.frame.height * 0.9)
        let pathAngle = CGFloat.random(in: 0...(CGFloat.pi * 2))
        imageView.center = CGPoint(x: startPointX, y: startPointY)
    
        //Calculate the endpoint from path angle and length
        let translationX = pathLength * sin(pathAngle)
        let translationY = (pathLength * cos(pathAngle))
    
        let endPointX = startPointX + translationX
        let endPointY = startPointY + translationY
    
        //Define the transitions for the aniamtion
        var transition1 = CGAffineTransform.identity
        transition1 = transition1.scaledBy(x: scaleFactor, y: scaleFactor)
    
    
        var transition2 = CGAffineTransform.identity
        transition2 = transition2.rotated(by: CGFloat.random(in: CGFloat.pi * 1/4 ... CGFloat.pi * 3/4))
    
    
    
        var transition3 = CGAffineTransform.identity
        transition3 = transition3.scaledBy(x: 0.001, y: 0.001)
    
    
    
    
        UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0, options: .beginFromCurrentState, animations: {
    
            imageView.transform = transition1
    
        }, completion: {finished in
    
            UIView.animate(withDuration: TimeInterval(pathDuration), delay: 0.5, options: [.beginFromCurrentState, .curveLinear], animations: {
    
                imageView.frame.origin = CGPoint(x: endPointX, y: endPointY)
                imageView.transform = transition2
    
            }, completion: { finished in
    
                UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0.5, options: .beginFromCurrentState, animations: {
    
                    imageView.transform = transition3
    
                }, completion: { finished in
    
                    imageView.removeFromSuperview()
    
                })
    
            })
    
        })
    
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-02
      • 2020-11-14
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 2011-09-13
      • 2014-11-15
      相关资源
      最近更新 更多