Skip to content

Instantly share code, notes, and snippets.

@allanweir
Last active July 8, 2017 14:22
Show Gist options
  • Save allanweir/badefea836590cfe61edae915b6e40bf to your computer and use it in GitHub Desktop.
Save allanweir/badefea836590cfe61edae915b6e40bf to your computer and use it in GitHub Desktop.
Lottie subclass for partial and reverse playback on iOS
//
// STAnimationView.swift
// Allan Weir
//
// Created by Allan Weir on 06/02/2017.
// Copyright © 2017 Allan Weir. All rights reserved.
// http://www.studiousdesigns.com
//
import UIKit
import Lottie
class STAnimationView: LOTAnimationView {
private var displayLink: CADisplayLink?
private var lastUpdateTime: CGFloat = 0
private var endTime: CGFloat = 1
private var lastTimeStamp: Date = Date()
private(set) var isPlayingReverse: Bool = false
class func animation(named animationName: String) -> STAnimationView {
let urlPath = Bundle.main.path(forResource: animationName, ofType: "json")!
return STAnimationView(contentsOf: URL(fileURLWithPath: urlPath))
}
func play(fromPosition: CGFloat, toPosition: CGFloat) {
if let oldLink = self.displayLink {
oldLink.invalidate()
}
self.displayLink = CADisplayLink(target: self, selector: #selector(STAnimationView.updateDisplayLink(link:)))
self.displayLink?.add(to: RunLoop.main, forMode: .defaultRunLoopMode)
self.isPlayingReverse = (toPosition < fromPosition)
self.lastUpdateTime = fromPosition
self.endTime = toPosition
self.animationProgress = fromPosition
self.lastTimeStamp = Date()
}
internal func updateDisplayLink(link: CADisplayLink) {
let newTime = Date()
let timePassed = newTime.timeIntervalSince(self.lastTimeStamp)
let deltaProgress = CGFloat(timePassed) * (self.animationSpeed / self.animationDuration)
var newProgress = !self.isPlayingReverse ? self.animationProgress + deltaProgress : self.animationProgress - deltaProgress
if !self.isPlayingReverse {
if newProgress >= self.endTime {
newProgress = self.endTime
self.displayLink?.invalidate()
self.displayLink = nil
}
} else {
if newProgress <= self.endTime {
newProgress = self.endTime
self.displayLink?.invalidate()
self.displayLink = nil
}
}
self.animationProgress = newProgress
self.lastTimeStamp = newTime
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment