Last active
November 8, 2020 06:12
-
-
Save OrkhanAlikhanov/79ce67a1739e7a4a4dba013d00663bd4 to your computer and use it in GitHub Desktop.
Revisions
-
OrkhanAlikhanov revised this gist
Sep 17, 2018 . 1 changed file with 16 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -14,7 +14,6 @@ private class TransitionAnimator { guard let layer = layer else { return } layer.speed = 1 layer.timeOffset = 0 let t = CACurrentMediaTime() @@ -40,44 +39,49 @@ private class TransitionAnimator { } pause() let s = CACurrentMediaTime() layer.setValue(s, forKey: "lastStartedAt") layer.beginTime = s let currentDuration = duration * 2 * CFTimeInterval(progress) layer.setValue(currentDuration, forKey: "currentDuration") layer.timeOffset = currentDuration } func pause() { guard let layer = layer else { return } let t = CACurrentMediaTime() layer.beginTime = t let currentDuration = (layer.value(forKey: "currentDuration") as! TimeInterval) + Double(layer.speed) * (t - (layer.value(forKey: "lastStartedAt") as! TimeInterval)) layer.setValue(currentDuration, forKey: "currentDuration") layer.speed = 0 layer.timeOffset = currentDuration } func resume() { guard let layer = layer else { return } layer.speed = 1 let s = CACurrentMediaTime() layer.setValue(s, forKey: "lastStartedAt") layer.beginTime = s } func cancel(isAnimated: Bool = true) { guard let layer = layer, let group = self.group else { return } guard isAnimated else { layer.removeAnimation(forKey: groupName) return } let newDuration = layer.timeOffset let newAnimations: [CABasicAnimation] = group.animations!.compactMap { $0 as? CABasicAnimation }.map { let a = CABasicAnimation() @@ -87,6 +91,7 @@ private class TransitionAnimator { return a } layer.removeAnimation(forKey: groupName) addGroup(newAnimations, duration: newDuration) } @@ -95,15 +100,10 @@ private class TransitionAnimator { return } group.animations!.compactMap { $0 as? CABasicAnimation }.forEach { layer.setValue($0.toValue, forKeyPath: $0.keyPath!) } resume() } } -
OrkhanAlikhanov created this gist
Sep 17, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,109 @@ private class TransitionAnimator { let groupName = "transition.group" weak var layer: CALayer? init(_ view: UIView) { self.layer = view.layer } private var group: CAAnimationGroup? { return layer?.animation(forKey: groupName) as? CAAnimationGroup } private func addGroup(_ animations: [CAAnimation], duration: TimeInterval) { guard let layer = layer else { return } layer.speed = 1 layer.timeOffset = 0 let t = CACurrentMediaTime() layer.beginTime = t layer.setValue(t, forKey: "lastStartedAt") layer.setValue(0, forKey: "currentDuration") layer.removeAllAnimations() let g = CAAnimationGroup() g.animations = animations g.duration = duration layer.add(g, forKey: groupName) } func start(_ animations: [CAAnimation], duration: TimeInterval) { addGroup(animations, duration: duration) pause() } func seek(_ progress: CGFloat) { guard let layer = layer, let duration = group?.duration else { return } pause() let s = CACurrentMediaTime() layer.setValue(s, forKey: "lastStartedAt") layer.beginTime = s let currentDuration = duration * CFTimeInterval(progress) layer.setValue(currentDuration, forKey: "currentDuration") layer.timeOffset = currentDuration } func pause() { guard let layer = layer else { return } let t = CACurrentMediaTime() layer.speed = 0 layer.beginTime = t let currentDuration = (layer.value(forKey: "currentDuration") as! TimeInterval) + t - (layer.value(forKey: "lastStartedAt") as! TimeInterval) layer.setValue(currentDuration, forKey: "currentDuration") layer.timeOffset = currentDuration } func resume() { guard let layer = layer else { return } layer.speed = 1 let s = CACurrentMediaTime() layer.setValue(s, forKey: "lastStartedAt") layer.beginTime = s } func cancel() { guard let layer = layer, let group = self.group else { return } let newDuration = layer.timeOffset let newAnimations: [CABasicAnimation] = group.animations!.compactMap { $0 as? CABasicAnimation }.map { let a = CABasicAnimation() a.keyPath = $0.keyPath a.toValue = layer.value(forKeyPath: $0.keyPath!) a.fromValue = layer.presentation()!.value(forKeyPath: $0.keyPath!) return a } addGroup(newAnimations, duration: newDuration) } func finish() { guard let layer = layer, let group = self.group else { return } let newDuration = group.duration - layer.timeOffset let newAnimations: [CABasicAnimation] = group.animations!.compactMap { $0 as? CABasicAnimation }.map { let a = CABasicAnimation() a.keyPath = $0.keyPath a.fromValue = layer.presentation()!.value(forKeyPath: $0.keyPath!) layer.setValue($0.toValue, forKeyPath: $0.keyPath!) return a } addGroup(newAnimations, duration: newDuration) } }