Skip to content

Commit

Permalink
fix incorrect duration when resuming
Browse files Browse the repository at this point in the history
  • Loading branch information
lkzhao committed Jul 14, 2017
1 parent 1534e40 commit bed1e05
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 23 deletions.
6 changes: 4 additions & 2 deletions Sources/Animator/HeroAnimatorViewContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ internal class HeroAnimatorViewContext {
func apply(state: HeroTargetState) {
}

func resume(timePassed: TimeInterval, reverse: Bool) {
func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval {
return 0
}

func seek(timePassed: TimeInterval) {
Expand All @@ -54,7 +55,8 @@ internal class HeroAnimatorViewContext {
animator = nil
}

func startAnimations() {
func startAnimations() -> TimeInterval {
return 0
}

required init(animator: HeroAnimator, snapshot: UIView, targetState: HeroTargetState, appearing: Bool) {
Expand Down
24 changes: 14 additions & 10 deletions Sources/Animator/HeroCoreAnimationViewContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ internal class HeroCoreAnimationViewContext: HeroAnimatorViewContext {
}
}

override func resume(timePassed: TimeInterval, reverse: Bool) {
override func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval {
for (key, (fromValue, toValue)) in state {
let realToValue = !reverse ? toValue : fromValue
let realFromValue = currentValue(key: key)
Expand All @@ -335,21 +335,25 @@ internal class HeroCoreAnimationViewContext: HeroAnimatorViewContext {
if reverse {
if timePassed > targetState.delay + duration {
let backDelay = timePassed - (targetState.delay + duration)
animate(beginTime: currentTime + backDelay, duration: duration)
return animate(delay: backDelay, duration: duration)
} else if timePassed > targetState.delay {
animate(beginTime: currentTime, duration: duration - (timePassed - targetState.delay))
return animate(delay: 0, duration: duration - (timePassed - targetState.delay))
} else {
return 0
}
} else {
if timePassed <= targetState.delay {
animate(beginTime: currentTime + targetState.delay - timePassed, duration: duration)
return animate(delay: targetState.delay - timePassed, duration: duration)
} else if timePassed <= targetState.delay + duration {
let timePassedDelay = timePassed - targetState.delay
animate(beginTime: currentTime, duration: duration - timePassedDelay)
return animate(delay: 0, duration: duration - timePassedDelay)
} else {
return 0
}
}
}

func animate(beginTime: TimeInterval, duration: TimeInterval) {
func animate(delay: TimeInterval, duration: TimeInterval) -> TimeInterval {
for (layer, key, _) in animations {
layer.removeAnimation(forKey: key)
}
Expand All @@ -362,11 +366,11 @@ internal class HeroCoreAnimationViewContext: HeroAnimatorViewContext {

animations = []
for (key, (fromValue, toValue)) in state {
let neededTime = animate(key: key, beginTime: beginTime, duration: duration, fromValue: fromValue, toValue: toValue)
let neededTime = animate(key: key, beginTime: currentTime + delay, duration: duration, fromValue: fromValue, toValue: toValue)
timeUntilStop = max(timeUntilStop, neededTime)
}

self.duration = timeUntilStop + beginTime - currentTime
return timeUntilStop + delay
}

func seek(layer: CALayer, timePassed: TimeInterval) {
Expand Down Expand Up @@ -394,7 +398,7 @@ internal class HeroCoreAnimationViewContext: HeroAnimatorViewContext {
overlayLayer = nil
}

override func startAnimations() {
override func startAnimations() -> TimeInterval {
if let beginStateModifiers = targetState.beginState {
let beginState = HeroTargetState(modifiers: beginStateModifiers)
let appeared = viewState(targetState: beginState)
Expand All @@ -417,6 +421,6 @@ internal class HeroCoreAnimationViewContext: HeroAnimatorViewContext {
state[key] = (fromValue, toValue)
}

animate(beginTime: currentTime + targetState.delay, duration: duration)
return animate(delay: targetState.delay, duration: duration)
}
}
11 changes: 4 additions & 7 deletions Sources/Animator/HeroDefaultAnimator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ internal class HeroDefaultAnimator<ViewContext: HeroAnimatorViewContext>: HeroAn
calculateOptimizedDuration(snapshot: viewContext.snapshot,
targetState: viewContext.targetState) + timePassed)
}
viewContext.resume(timePassed: timePassed, reverse: reverse)
duration = max(duration, viewContext.duration)
let timeUntilStopped = viewContext.resume(timePassed: timePassed, reverse: reverse)
duration = max(duration, timeUntilStopped)
}
return duration
}
Expand Down Expand Up @@ -105,11 +105,8 @@ internal class HeroDefaultAnimator<ViewContext: HeroAnimatorViewContext>: HeroAn
if viewContext.targetState.duration == .infinity {
viewContext.duration = maxDuration
}
viewContext.startAnimations()
}

for viewContext in viewContexts.values {
maxDuration = max(maxDuration, viewContext.duration)
let timeUntilStopped = viewContext.startAnimations()
maxDuration = max(maxDuration, timeUntilStopped)
}

return maxDuration
Expand Down
10 changes: 6 additions & 4 deletions Sources/Animator/HeroViewPropertyViewContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@ internal class HeroViewPropertyViewContext: HeroAnimatorViewContext {
return view is UIVisualEffectView && state.opacity != nil
}

override func resume(timePassed: TimeInterval, reverse: Bool) {
guard let visualEffectView = snapshot as? UIVisualEffectView else { return }
override func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval {
guard let visualEffectView = snapshot as? UIVisualEffectView else { return 0 }
if reverse {
viewPropertyAnimator?.stopAnimation(false)
viewPropertyAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
visualEffectView.effect = reverse ? self.startEffect : self.endEffect
}
}
viewPropertyAnimator.startAnimation()
return duration
}

override func seek(timePassed: TimeInterval) {
Expand All @@ -54,8 +55,8 @@ internal class HeroViewPropertyViewContext: HeroAnimatorViewContext {
viewPropertyAnimator = nil
}

override func startAnimations() {
guard let visualEffectView = snapshot as? UIVisualEffectView else { return }
override func startAnimations() -> TimeInterval {
guard let visualEffectView = snapshot as? UIVisualEffectView else { return 0 }
let appearedEffect = visualEffectView.effect
let disappearedEffect = targetState.opacity == 0 ? nil : visualEffectView.effect
startEffect = appearing ? disappearedEffect : appearedEffect
Expand All @@ -65,5 +66,6 @@ internal class HeroViewPropertyViewContext: HeroAnimatorViewContext {
visualEffectView.effect = self.endEffect
}
viewPropertyAnimator.startAnimation()
return duration
}
}

0 comments on commit bed1e05

Please sign in to comment.