使用UIViewPropertyAnimator按顺序制作UIView的alpha动画

时间:2017-03-23 09:03:38

标签: ios swift xcode uiview

我有一个想要在0.5秒后显示的UIView,并在0.5秒后再次隐藏,创建一个简单的动画。我的代码如下:

    let animation = UIViewPropertyAnimator.init(duration: 0.5, curve: .linear) {
        self.timerBackground.alpha = 1
        let transition = UIViewPropertyAnimator.init(duration: 0.5, curve: .linear) {
            self.timerBackground.alpha = 0
        }
        transition.startAnimation(afterDelay: 0.5)
    }
    animation.startAnimation()

当我测试它时,没有任何反应。我认为这是因为它们都在同一时间运行,这意味着它们相互抵消,但这不是“afterDelay”部分应该阻止的吗?

如果我单独运行它们,即从隐藏变为可见,或者从隐藏变为可见,它可以工作,但是当我尝试按顺序运行它时,它不起作用。

我的UIView不是不透明或隐藏的。

3 个答案:

答案 0 :(得分:6)

您可以使用Timer,并在每个计时器标记处向您的UIViewPropertyAnimator对象添加显示/隐藏动画块。

这是一个代码库:

@IBOutlet weak var timerBackground: UIImageView!

private var timer: Timer?
private var isShown = false
private var viewAnimator = UIViewPropertyAnimator.init(duration: 0.5, curve: .linear)

override func viewDidLoad() {
    super.viewDidLoad()
    viewAnimator.addAnimations {
        self.timerBackground.alpha = 1
    }
    viewAnimator.startAnimation()
    isShown = true

    self.timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.startReversedAction), userInfo: nil, repeats: true)
}

func startReversedAction() {
    // stop the previous animations block if it did not have time to finish its movement
    viewAnimator.stopAnimation(true)
    viewAnimator.addAnimations ({
        self.timerBackground.alpha = self.isShown ? 0 : 1
    })
    viewAnimator.startAnimation()
    isShown  =  !isShown
}

我已为dots jumpingiOS 10 Animations demo project实施了非常相似的行为。

请随时查看以获取更多详细信息。

答案 1 :(得分:1)

使用UIView.animateKeyframes如果你有复杂的动画,你可以很好地构建你的代码。如果你将UIView动画嵌套在其他人的完成块中,它可能会导致荒谬的缩进级别和零可读性。

以下是一个例子:

/* Target frames to move our object to (and animate)
   or it could be alpha property in your case... */

let newFrameOne = CGRect(x: 200, y: 50, width: button.bounds.size.width, height: button.bounds.size.height)
let newFrameTwo = CGRect(x: 300, y: 200, width: button.bounds.size.width, height: button.bounds.size.height)

UIView.animateKeyframes(withDuration: 2.0,
                               delay: 0.0,
                             options: .repeat,
                          animations: { _ in
    /* First animation */                                    
    UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5, animations: { [weak self] in
        self?.button.frame = newFrameOne
    })

    /* Second animation */                                    
    UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: { [weak self] in
        self?.button.frame = newFrameTwo
    })

    /* . . . */  

    }, completion: nil)

答案 2 :(得分:0)

对我有用的是使用 UIViewPropertyAnimators 序列。这是我的代码示例:

let animator1 = UIViewPropertyAnimator(duration:1, curve: .easeIn)
        animator1.addAnimations {
            smallCoin.transform = CGAffineTransform(scaleX: 4, y: 4)
            smallCoin.center = center
        }
        let animator2 = UIViewPropertyAnimator(duration:1, curve: .easeIn)
        animator2.addAnimations {
            center.y -= 20
            smallCoin.center = center
        }
        let animator3 = UIViewPropertyAnimator(duration:10, curve: .easeIn)
        animator3.addAnimations {
            smallCoin.alpha = 0
        }
        animator1.addCompletion { _ in
            animator2.startAnimation()
          }
        animator2.addCompletion { _ in
            animator3.startAnimation()
          }
        animator3.addCompletion ({ _ in
            print("finished")
        })
        animator1.startAnimation()

您甚至可以添加 afterdelay 属性来管理动画速度。

animator3.startAnimation(afterDelay: 10)