简体   繁体   中英

Animate UIView along BezierPath with delay

I want to animate a UIView in a figure 8 motion. I am doing this in Swift using BezierPath but I want to add a delay to the animation.

let center: CGPoint = CGPoint(x: 60, y: 45)
let cent: CGPoint = CGPoint(x: 90, y: 45)
let radius: CGFloat = 15.0
let start: CGFloat = CGFloat(M_PI)
let end: CGFloat = 0.0
let path1: UIBezierPath = UIBezierPath(arcCenter: center, radius: radius, startAngle: start, endAngle: end, clockwise: true)
let path2: UIBezierPath = UIBezierPath(arcCenter: cent, radius: radius, startAngle: -start, endAngle: end, clockwise: false)
let path3: UIBezierPath = UIBezierPath(arcCenter: cent, radius: radius, startAngle: end, endAngle: -start, clockwise: false)
let path4: UIBezierPath = UIBezierPath(arcCenter: center, radius: radius, startAngle: end, endAngle: start, clockwise: true)
let paths: UIBezierPath = UIBezierPath()
paths.appendPath(path1)
paths.appendPath(path2)
paths.appendPath(path3)
paths.appendPath(path4)

let anim: CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position")
anim.path = paths.CGPath
anim.repeatCount = 2.0
anim.duration = 3.0

view.layer.addAnimation(anim, forKey: "animate position along path")

The figure 8 works just fine, but I have no idea how to add a delay. I have tried using methods like animateWithDuration(delay:options:animation:completion:) but that didn't help. If I am way off base and there is an easier way to animate a UIView in a 'Figure 8'/'Inifinity Loop' motion that would be fine. I just need the motion coupled with the delay.

Animation objects have a start time. Set that to the future by whatever amount you want.

anim.beginTime = CACurrentMediaTime() + 1.0

This example will delay the start by 1 second.

Using a dispatch_after block to kick off the entire animation method may achieve the same result in the short run, but could inhibit the ability to adjust or manipulate additional timing functions on the animation relative to it's start time in the future. Adjusting the time on the animation itself keeps your animation object's timing state consistent.

If you want the animation to trigger after a delay you can try triggering the animation in a function like this:

func executeWithDelay(_ delay: NSTimeInterval, block: dispatch_block_t) {
    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
    dispatch_after(delay, dispatch_get_main_queue(), block)
}

and use it like:

executeWithDelay(1.0) {
   //trigger animation
}

The above example will trigger the block after 1.0 second.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM