iOS Swift:在旋转动画中间更改imageview图片

时间:2018-07-16 08:36:16

标签: ios swift image animation

我有开本动画:https://streamable.com/n1c0n

我想在90度上改变图像。

我使用以下代码:

var book1ImageViewI : UIImageView
let book2ImageViewI : UIImageView

book1ImageViewI = UIImageView(frame: CGRect( x: self.view.frame.size.width / 2 - 140, y: (self.view.frame.size.height / 2) - ( (self.view.frame.width / 2) / 2 ), width: ( (self.view.frame.width / 2) / 8) * 7, height: self.view.frame.width / 2))

book2ImageViewI = UIImageView(frame: CGRect(x: self.view.frame.size.width / 2 - 140, y: (self.view.frame.size.height / 2) - ( (self.view.frame.width / 2) / 2 ), width: ( (self.view.frame.width / 2) / 8) * 7, height: self.view.frame.width / 2))


book1ImageViewI.image = UIImage(named:"attachment_83090027.jpg")
book2ImageViewI.image = UIImage(named:"0a6752b7cd35fc441c152238ee5078384d--antique-books-rabbit-hole.jpg")

book1ImageViewI.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
book2ImageViewI.layer.anchorPoint = CGPoint(x: 0, y: 0.5)

var transform = CATransform3DIdentity
transform.m34 = 1.0 / -2000.0
book1ImageViewI.layer.transform = transform

UIView.animate(withDuration: 1.5, animations: {
    book1ImageViewI.layer.transform = CATransform3DRotate(transform, -.pi/2, 0, 1, 0)
})
{
    (bCompleted) in
    if (bCompleted) {
        book1ImageViewI.layer.transform = CATransform3DRotate(transform, -.pi/2, 0, 1, 0)
    }

    UIView.animate(withDuration: 1.5, animations: {
        book1ImageViewI.layer.transform = CATransform3DRotate(transform, .pi*0.999, 0, 1, 0)
        book1ImageViewI.image = UIImage(named:"0a6752b7cd35fc441c1528ee5078384d--antique-books-rabbit-holer.png")
        }, completion: {
            (bFinished) in
            //Whatever
    })
}

self.view.addSubview(book2ImageViewI)
self.view.addSubview(book1ImageViewI)

一切正常。但是在90度动画上略有延迟。

我想立即获得这样的动画:https://streamable.com/q2bf6

如何做到?

P.S。在第二个动画中,使用以下代码:

UIView.animate(withDuration: 3,  delay: 0.0,
                       options: [], animations: {

    DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
        book1ImageViewI.image = UIImage(named:"0a6752b7cd35fc441c1528ee5078384d--antique-books-rabbit-holer.png")
    }

    book1ImageViewI.layer.transform = CATransform3DRotate(transform, .pi, 0, 1, 0)

    self.view.layoutIfNeeded()

    }, completion: {_ in

})

但是此代码不适合。因为图像的变化不是90度。有时更早。有时以后。

2 个答案:

答案 0 :(得分:0)

这部分代码冲突:

AJAX

您将(bCompleted) in if (bCompleted) { book1ImageViewI.layer.transform = CATransform3DRotate(transform, -.pi/2, 0, 1, 0) } UIView.animate(withDuration: 1.5, animations: { book1ImageViewI.layer.transform = CATransform3DRotate(transform, .pi*0.999, 0, 1, 0) book1ImageViewI.image = UIImage(named:"0a6752b7cd35fc441c1528ee5078384d--antique-books-rabbit-holer.png") }, completion: { (bFinished) in //Whatever }) book1ImageViewI.layer.transform = CATransform3DRotate(transform, -.pi/2, 0, 1, 0)同时设置

尝试以下方法:

book1ImageViewI.layer.transform = CATransform3DRotate(transform, .pi*0.999, 0, 1, 0)

答案 1 :(得分:0)

显然,在涉及旋转变换的任何地方,锚点更改都是非常关键的,而且并非一帆风顺。每次更改锚点时,它都会更改UIView的位置,我们必须以某种方式补偿此更改。

这是使用imageview的最终版本,它对我来说没有中断。显然,它也可以与addKeyFrame API一起使用,但为简单起见,我保留了UIView.animate().

我使用的技巧是使第一个动画的持续时间较小,而第二个动画的持续时间较大。它几乎就像翻页一样。您还可以使用提供UIViewAnimationOptions的UIView.animate覆盖(例如curveEaseIn和curveEaseOut)使其看起来像一本书的页面翻转。

这似乎对我有用,唯一的是您不能说它是从正面或背面旋转的。如果您的imageview是倾斜的(例如您在视频中显示的倾斜的书页),则它应该是可见的,并且您可以通过在CATransform3DRotate参数中将-改为+来进行更正,或者在动画中反之亦然

注意:

如果它仍在隐藏和搜索,请尝试在真实设备上而不是模拟器上以防万一。在动画方面,由于GPU的执行存在明显差异。

func pageFlipAnimation()
{
    self.myImageView.image = UIImage.init(named: "firstImage")

    var transform = CATransform3DIdentity
    let transform1 = CATransform3DRotate(transform, -CGFloat(Double.pi)*0.5, 0, 1, 0)
    let transform2 = CATransform3DRotate(transform, -CGFloat(Double.pi), 0, 1, 0)

    transform.m34 = 1.0 / -5000.0

    self.setAnchorPoint(anchorPoint: CGPoint(x: 0, y: 0.5), forView: self.myImageView)

    UIView.animate(withDuration: 0.5, animations:
    {
        self.myImageView.layer.transform = transform1
    })
    {
        (bFinished) in
        self.myImageView.image = UIImage.init(named: "secondImage")

        UIView.animate(withDuration: 0.75, animations:
        {
             self.myImageView.layer.transform = transform2
        })
    }
}

//This should ideally be a UIView Extension
func setAnchorPoint(anchorPoint: CGPoint, forView view: UIView)
{
    var newPoint = CGPoint(x:view.bounds.size.width * anchorPoint.x, y:view.bounds.size.height * anchorPoint.y)
    var oldPoint = CGPoint(x:view.bounds.size.width * view.layer.anchorPoint.x, y:view.bounds.size.height * view.layer.anchorPoint.y)

    newPoint = newPoint.applying(view.transform)
    oldPoint = oldPoint.applying(view.transform)

    var position = view.layer.position
    position.x -= oldPoint.x
    position.x += newPoint.x

    position.y -= oldPoint.y
    position.y += newPoint.y

    view.layer.position = position
    view.layer.anchorPoint = anchorPoint
}