Commit df2f0742 by Daniel Dahan

development: refined prepare statements for MotionTransition

parent e352f7a9
...@@ -222,6 +222,8 @@ open class MotionTransitionPresentationController: UIPresentationController { ...@@ -222,6 +222,8 @@ open class MotionTransitionPresentationController: UIPresentationController {
open class MotionTransition: NSObject { open class MotionTransition: NSObject {
open var isPresenting: Bool open var isPresenting: Bool
open fileprivate(set) var transitionPairs = [(UIView, UIView)]()
open var transitionSnapshot: UIView! open var transitionSnapshot: UIView!
open let transitionBackgroundView = UIView() open let transitionBackgroundView = UIView()
...@@ -289,6 +291,7 @@ extension MotionTransition: UIViewControllerAnimatedTransitioning { ...@@ -289,6 +291,7 @@ extension MotionTransition: UIViewControllerAnimatedTransitioning {
prepareFromViewController() prepareFromViewController()
prepareContainerView() prepareContainerView()
prepareTransitionSnapshot() prepareTransitionSnapshot()
prepareTransitionPairs()
prepareTransitionView() prepareTransitionView()
prepareTransitionBackgroundView() prepareTransitionBackgroundView()
prepareTransitionToView() prepareTransitionToView()
...@@ -326,6 +329,21 @@ extension MotionTransition { ...@@ -326,6 +329,21 @@ extension MotionTransition {
containerView.addSubview(transitionSnapshot) containerView.addSubview(transitionSnapshot)
} }
fileprivate func prepareTransitionPairs() {
for from in fromSubviews {
for to in toSubviews {
guard 0 < from.motionTransitionAnimations.count else {
return
}
guard to.motionTransitionIdentifier == from.motionTransitionIdentifier else {
continue
}
transitionPairs.append((from, to))
}
}
}
fileprivate func prepareTransitionView() { fileprivate func prepareTransitionView() {
transitionView.frame = containerView.bounds transitionView.frame = containerView.bounds
...@@ -361,73 +379,52 @@ extension MotionTransition { ...@@ -361,73 +379,52 @@ extension MotionTransition {
extension MotionTransition { extension MotionTransition {
fileprivate func addTransitionAnimations() { fileprivate func addTransitionAnimations() {
for fv in fromSubviews { for (from, to) in transitionPairs {
for tv in toSubviews { let t = motionDelay(animations: to.motionTransitionAnimations)
if tv.motionTransitionIdentifier == fv.motionTransitionIdentifier { let d = motionDuration(animations: to.motionTransitionAnimations)
var t: TimeInterval = 0
var d: TimeInterval = 0 var snapshotAnimations = [CABasicAnimation]()
var tf = MotionAnimationTimingFunction.easeInEaseOut var snapshotChildAnimations = [CABasicAnimation]()
for ta in tv.motionTransitionAnimations { let sizeAnimation = Motion.size(to.bounds.size)
switch ta { let cornerRadiusAnimation = Motion.corner(radius: to.cornerRadius)
case let .delay(time):
if time > delay { snapshotAnimations.append(sizeAnimation)
delay = time snapshotAnimations.append(cornerRadiusAnimation)
} snapshotAnimations.append(Motion.position(to: to.motionPosition))
t = time snapshotAnimations.append(Motion.rotation(angle: to.motionRotationAngle))
case let .duration(time): snapshotAnimations.append(Motion.background(color: to.backgroundColor ?? .clear))
if time > duration {
duration = time snapshotChildAnimations.append(cornerRadiusAnimation)
} snapshotChildAnimations.append(sizeAnimation)
d = time snapshotChildAnimations.append(Motion.position(x: to.bounds.width / 2, y: to.bounds.height / 2))
default:break
} let snapshot = from.motionTransitionSnapshot(afterUpdates: true)
} transitionView.addSubview(snapshot)
var snapshotAnimations = [CABasicAnimation]() Motion.delay(t) { [weak self, weak to] in
var snapshotChildAnimations = [CABasicAnimation]() guard let s = self else {
return
let sizeAnimation = Motion.size(tv.bounds.size)
let cornerRadiusAnimation = Motion.corner(radius: tv.cornerRadius)
snapshotAnimations.append(sizeAnimation)
snapshotAnimations.append(cornerRadiusAnimation)
snapshotAnimations.append(Motion.position(to: tv.motionPosition))
snapshotAnimations.append(Motion.rotation(angle: tv.motionRotationAngle))
snapshotAnimations.append(Motion.background(color: tv.backgroundColor ?? .clear))
snapshotChildAnimations.append(cornerRadiusAnimation)
snapshotChildAnimations.append(sizeAnimation)
snapshotChildAnimations.append(Motion.position(x: tv.bounds.width / 2, y: tv.bounds.height / 2))
let snapshot = fv.motionTransitionSnapshot(afterUpdates: true)
transitionView.addSubview(snapshot)
Motion.delay(t) {
for ta in tv.motionTransitionAnimations {
switch ta {
case let .timingFunction(timingFunction):
tf = timingFunction
case let .shadow(path):
snapshotAnimations.append(Motion.shadow(path: path))
default:break
}
}
let snapshotGroup = Motion.animate(group: snapshotAnimations, duration: d)
snapshotGroup.fillMode = MotionAnimationFillModeToValue(mode: .forwards)
snapshotGroup.isRemovedOnCompletion = false
snapshotGroup.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf)
let snapshotChildGroup = Motion.animate(group: snapshotChildAnimations, duration: d)
snapshotChildGroup.fillMode = MotionAnimationFillModeToValue(mode: .forwards)
snapshotChildGroup.isRemovedOnCompletion = false
snapshotChildGroup.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf)
snapshot.animate(snapshotGroup)
snapshot.subviews.first!.animate(snapshotChildGroup)
}
} }
guard let v = to else {
return
}
let tf = s.motionTimingFunction(animations: v.motionTransitionAnimations)
let snapshotGroup = Motion.animate(group: snapshotAnimations, duration: d)
snapshotGroup.fillMode = MotionAnimationFillModeToValue(mode: .forwards)
snapshotGroup.isRemovedOnCompletion = false
snapshotGroup.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf)
let snapshotChildGroup = Motion.animate(group: snapshotChildAnimations, duration: d)
snapshotChildGroup.fillMode = MotionAnimationFillModeToValue(mode: .forwards)
snapshotChildGroup.isRemovedOnCompletion = false
snapshotChildGroup.timingFunction = MotionAnimationTimingFunctionToValue(timingFunction: tf)
snapshot.animate(snapshotGroup)
snapshot.subviews.first!.animate(snapshotChildGroup)
} }
} }
} }
...@@ -438,6 +435,50 @@ extension MotionTransition { ...@@ -438,6 +435,50 @@ extension MotionTransition {
} }
extension MotionTransition { extension MotionTransition {
fileprivate func motionDelay(animations: [MotionAnimation]) -> TimeInterval {
var t: TimeInterval = 0
for a in animations {
switch a {
case let .delay(time):
if time > delay {
delay = time
}
t = time
default:break
}
}
return t
}
fileprivate func motionDuration(animations: [MotionAnimation]) -> TimeInterval {
var t: TimeInterval = 0
for a in animations {
switch a {
case let .duration(time):
if time > duration {
duration = time
}
t = time
default:break
}
}
return t
}
fileprivate func motionTimingFunction(animations: [MotionAnimation]) -> MotionAnimationTimingFunction {
var t = MotionAnimationTimingFunction.easeInEaseOut
for a in animations {
switch a {
case let .timingFunction(timingFunction):
t = timingFunction
default:break
}
}
return t
}
}
extension MotionTransition {
fileprivate func cleanupAnimation() { fileprivate func cleanupAnimation() {
Motion.delay(transitionDuration(using: transitionContext)) { [weak self] in Motion.delay(transitionDuration(using: transitionContext)) { [weak self] in
guard let s = self else { guard let s = self else {
...@@ -446,6 +487,7 @@ extension MotionTransition { ...@@ -446,6 +487,7 @@ extension MotionTransition {
s.hideToSubviews() s.hideToSubviews()
s.clearTransitionView() s.clearTransitionView()
s.clearTransitionPairs()
s.completeTransition() s.completeTransition()
} }
} }
...@@ -468,6 +510,10 @@ extension MotionTransition { ...@@ -468,6 +510,10 @@ extension MotionTransition {
} }
} }
fileprivate func clearTransitionPairs() {
transitionPairs.removeAll()
}
fileprivate func clearTransitionView() { fileprivate func clearTransitionView() {
transitionView.removeFromSuperview() transitionView.removeFromSuperview()
transitionView.subviews.forEach { transitionView.subviews.forEach {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment