Commit c10fe806 by Daniel Dahan

combined MotionCoreAnimator and MotionTransitionAnimator

parent 470bb0fb
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
96E409651F24F7370015A2B5 /* MotionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E4093D1F24F7370015A2B5 /* MotionAnimator.swift */; }; 96E409651F24F7370015A2B5 /* MotionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E4093D1F24F7370015A2B5 /* MotionAnimator.swift */; };
96E409661F24F7370015A2B5 /* MotionAnimatorViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */; }; 96E409661F24F7370015A2B5 /* MotionAnimatorViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */; };
96E409671F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */; }; 96E409671F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */; };
96E409691F24F7370015A2B5 /* MotionTransitionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E409411F24F7370015A2B5 /* MotionTransitionAnimator.swift */; };
96E4096A1F24F7370015A2B5 /* MotionViewPropertyViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */; }; 96E4096A1F24F7370015A2B5 /* MotionViewPropertyViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */; };
96E4096B1F24F7370015A2B5 /* Motion+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E409441F24F7370015A2B5 /* Motion+Array.swift */; }; 96E4096B1F24F7370015A2B5 /* Motion+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E409441F24F7370015A2B5 /* Motion+Array.swift */; };
96E4096C1F24F7370015A2B5 /* Motion+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E409451F24F7370015A2B5 /* Motion+CALayer.swift */; }; 96E4096C1F24F7370015A2B5 /* Motion+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E409451F24F7370015A2B5 /* Motion+CALayer.swift */; };
...@@ -64,7 +63,6 @@ ...@@ -64,7 +63,6 @@
96E409891F24F7570015A2B5 /* MotionAnimator.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E4093D1F24F7370015A2B5 /* MotionAnimator.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96E409891F24F7570015A2B5 /* MotionAnimator.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E4093D1F24F7370015A2B5 /* MotionAnimator.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96E4098A1F24F7570015A2B5 /* MotionAnimatorViewContext.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96E4098A1F24F7570015A2B5 /* MotionAnimatorViewContext.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96E4098B1F24F7570015A2B5 /* MotionCoreAnimationViewContext.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96E4098B1F24F7570015A2B5 /* MotionCoreAnimationViewContext.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96E4098D1F24F7570015A2B5 /* MotionTransitionAnimator.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E409411F24F7370015A2B5 /* MotionTransitionAnimator.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96E4098E1F24F7570015A2B5 /* MotionViewPropertyViewContext.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96E4098E1F24F7570015A2B5 /* MotionViewPropertyViewContext.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96E4098F1F24F7570015A2B5 /* Motion+Array.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E409441F24F7370015A2B5 /* Motion+Array.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96E4098F1F24F7570015A2B5 /* Motion+Array.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E409441F24F7370015A2B5 /* Motion+Array.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96E409901F24F7570015A2B5 /* Motion+CALayer.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E409451F24F7370015A2B5 /* Motion+CALayer.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96E409901F24F7570015A2B5 /* Motion+CALayer.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E409451F24F7370015A2B5 /* Motion+CALayer.swift */; settings = {ATTRIBUTES = (Public, ); }; };
...@@ -112,7 +110,6 @@ ...@@ -112,7 +110,6 @@
96E4093D1F24F7370015A2B5 /* MotionAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionAnimator.swift; sourceTree = "<group>"; }; 96E4093D1F24F7370015A2B5 /* MotionAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionAnimator.swift; sourceTree = "<group>"; };
96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionAnimatorViewContext.swift; sourceTree = "<group>"; }; 96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionAnimatorViewContext.swift; sourceTree = "<group>"; };
96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionCoreAnimationViewContext.swift; sourceTree = "<group>"; }; 96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionCoreAnimationViewContext.swift; sourceTree = "<group>"; };
96E409411F24F7370015A2B5 /* MotionTransitionAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionTransitionAnimator.swift; sourceTree = "<group>"; };
96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionViewPropertyViewContext.swift; sourceTree = "<group>"; }; 96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionViewPropertyViewContext.swift; sourceTree = "<group>"; };
96E409441F24F7370015A2B5 /* Motion+Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Motion+Array.swift"; sourceTree = "<group>"; }; 96E409441F24F7370015A2B5 /* Motion+Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Motion+Array.swift"; sourceTree = "<group>"; };
96E409451F24F7370015A2B5 /* Motion+CALayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Motion+CALayer.swift"; sourceTree = "<group>"; }; 96E409451F24F7370015A2B5 /* Motion+CALayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Motion+CALayer.swift"; sourceTree = "<group>"; };
...@@ -210,7 +207,6 @@ ...@@ -210,7 +207,6 @@
965FE96C1FDDA6400098BDD0 /* MotionCoreAnimator.swift */, 965FE96C1FDDA6400098BDD0 /* MotionCoreAnimator.swift */,
96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */, 96E4093E1F24F7370015A2B5 /* MotionAnimatorViewContext.swift */,
96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */, 96E4093F1F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift */,
96E409411F24F7370015A2B5 /* MotionTransitionAnimator.swift */,
96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */, 96E409421F24F7370015A2B5 /* MotionViewPropertyViewContext.swift */,
); );
path = Animator; path = Animator;
...@@ -257,7 +253,6 @@ ...@@ -257,7 +253,6 @@
96E409891F24F7570015A2B5 /* MotionAnimator.swift in Headers */, 96E409891F24F7570015A2B5 /* MotionAnimator.swift in Headers */,
96E4098A1F24F7570015A2B5 /* MotionAnimatorViewContext.swift in Headers */, 96E4098A1F24F7570015A2B5 /* MotionAnimatorViewContext.swift in Headers */,
96E4098B1F24F7570015A2B5 /* MotionCoreAnimationViewContext.swift in Headers */, 96E4098B1F24F7570015A2B5 /* MotionCoreAnimationViewContext.swift in Headers */,
96E4098D1F24F7570015A2B5 /* MotionTransitionAnimator.swift in Headers */,
96E4098E1F24F7570015A2B5 /* MotionViewPropertyViewContext.swift in Headers */, 96E4098E1F24F7570015A2B5 /* MotionViewPropertyViewContext.swift in Headers */,
96E4098F1F24F7570015A2B5 /* Motion+Array.swift in Headers */, 96E4098F1F24F7570015A2B5 /* Motion+Array.swift in Headers */,
96E409901F24F7570015A2B5 /* Motion+CALayer.swift in Headers */, 96E409901F24F7570015A2B5 /* Motion+CALayer.swift in Headers */,
...@@ -370,7 +365,6 @@ ...@@ -370,7 +365,6 @@
96E409781F24F7370015A2B5 /* MotionCAAnimation.swift in Sources */, 96E409781F24F7370015A2B5 /* MotionCAAnimation.swift in Sources */,
96E409811F24F7370015A2B5 /* MotionTargetState.swift in Sources */, 96E409811F24F7370015A2B5 /* MotionTargetState.swift in Sources */,
96E409801F24F7370015A2B5 /* MotionTransitionObserver.swift in Sources */, 96E409801F24F7370015A2B5 /* MotionTransitionObserver.swift in Sources */,
96E409691F24F7370015A2B5 /* MotionTransitionAnimator.swift in Sources */,
96E409651F24F7370015A2B5 /* MotionAnimator.swift in Sources */, 96E409651F24F7370015A2B5 /* MotionAnimator.swift in Sources */,
96E409671F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift in Sources */, 96E409671F24F7370015A2B5 /* MotionCoreAnimationViewContext.swift in Sources */,
96E4096D1F24F7370015A2B5 /* Motion+CAMediaTimingFunction.swift in Sources */, 96E4096D1F24F7370015A2B5 /* Motion+CAMediaTimingFunction.swift in Sources */,
......
...@@ -30,7 +30,7 @@ import UIKit ...@@ -30,7 +30,7 @@ import UIKit
internal class MotionAnimatorViewContext { internal class MotionAnimatorViewContext {
/// An optional reference to a MotionAnimator. /// An optional reference to a MotionAnimator.
var animator: MotionCoreAnimator? var animator: MotionAnimator?
/// A reference to the snapshot UIView. /// A reference to the snapshot UIView.
var snapshot: UIView var snapshot: UIView
...@@ -51,7 +51,7 @@ internal class MotionAnimatorViewContext { ...@@ -51,7 +51,7 @@ internal class MotionAnimatorViewContext {
/// A container view for the transition. /// A container view for the transition.
var container: UIView? { var container: UIView? {
return animator?.context.container return animator?.motion.context.container
} }
/** /**
...@@ -61,7 +61,7 @@ internal class MotionAnimatorViewContext { ...@@ -61,7 +61,7 @@ internal class MotionAnimatorViewContext {
- Parameter targetState: A MotionModifier. - Parameter targetState: A MotionModifier.
- Parameter isAppearing: A Boolean. - Parameter isAppearing: A Boolean.
*/ */
required init(animator: MotionCoreAnimator, snapshot: UIView, targetState: MotionTargetState, isAppearing: Bool) { required init(animator: MotionAnimator, snapshot: UIView, targetState: MotionTargetState, isAppearing: Bool) {
self.animator = animator self.animator = animator
self.snapshot = snapshot self.snapshot = snapshot
self.targetState = targetState self.targetState = targetState
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
import UIKit import UIKit
class MotionCoreAnimator: MotionAnimator { internal class MotionCoreAnimator<T: MotionAnimatorViewContext>: MotionAnimator {
weak public var motion: MotionTransition! weak public var motion: MotionTransition!
/// A reference to the MotionContext. /// A reference to the MotionContext.
...@@ -36,23 +36,131 @@ class MotionCoreAnimator: MotionAnimator { ...@@ -36,23 +36,131 @@ class MotionCoreAnimator: MotionAnimator {
return motion.context return motion.context
} }
func clean() {} /// An index of views to their corresponding animator context.
var viewToContexts = [UIView: T]()
/// Cleans the contexts.
func clean() {
for v in viewToContexts.values {
v.clean()
}
viewToContexts.removeAll()
}
/**
A function that determines if a view can be animated.
- Parameter view: A UIView.
- Parameter isAppearing: A boolean that determines whether the
view is appearing.
*/
func canAnimate(view: UIView, isAppearing: Bool) -> Bool { func canAnimate(view: UIView, isAppearing: Bool) -> Bool {
return false guard let state = context[view] else {
return false
}
return T.canAnimate(view: view, state: state, isAppearing: isAppearing)
} }
/**
Animates the fromViews to the toViews.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
- Returns: A TimeInterval.
*/
func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval {
return 0 var d: TimeInterval = 0
for v in fromViews {
createViewContext(view: v, isAppearing: false)
}
for v in toViews {
createViewContext(view: v, isAppearing: true)
}
for v in viewToContexts.values {
if let duration = v.targetState.duration, .infinity != duration {
v.duration = duration
d = max(d, duration)
} else {
let duration = v.snapshot.optimizedDuration(targetState: v.targetState)
if nil == v.targetState.duration {
v.duration = duration
}
d = max(d, duration)
}
}
for v in viewToContexts.values {
if .infinity == v.targetState.duration {
v.duration = d
}
d = max(d, v.startAnimations())
}
return d
} }
func seek(to progress: TimeInterval) {} /**
Moves the view's animation to the given elapsed time.
- Parameter to progress: A TimeInterval.
*/
func seek(to progress: TimeInterval) {
for v in viewToContexts.values {
v.seek(to: progress)
}
}
/**
Resumes the animation with a given elapsed time and
optional reversed boolean.
- Parameter at progress: A TimeInterval.
- Parameter isReversed: A boolean to reverse the animation
or not.
*/
func resume(at progress: TimeInterval, isReversed: Bool) -> TimeInterval { func resume(at progress: TimeInterval, isReversed: Bool) -> TimeInterval {
return 0 var duration: TimeInterval = 0
for (_, v) in viewToContexts {
if nil == v.targetState.duration {
v.duration = max(v.duration, v.snapshot.optimizedDuration(targetState: v.targetState) + progress)
}
duration = max(duration, v.resume(at: progress, isReversed: isReversed))
}
return duration
} }
func apply(state: MotionTargetState, to view: UIView) {} /**
Applies the given state to the given view.
- Parameter state: A MotionModifier.
- Parameter to view: A UIView.
*/
func apply(state: MotionTargetState, to view: UIView) {
guard let v = viewToContexts[view] else {
return
}
v.apply(state: state)
}
}
fileprivate extension MotionCoreAnimator {
/**
Creates a view context for a given view.
- Parameter view: A UIView.
- Parameter isAppearing: A boolean that determines whether the
view is appearing.
*/
func createViewContext(view: UIView, isAppearing: Bool) {
viewToContexts[view] = T(animator: self, snapshot: context.snapshotView(for: view), targetState: context[view]!, isAppearing: isAppearing)
}
} }
/*
* The MIT License (MIT)
*
* Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>.
* All rights reserved.
*
* Original Inspiration & Author
* Copyright (c) 2016 Luke Zhao <me@lkzhao.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import UIKit
internal class MotionTargetStateAnimator<T: MotionAnimatorViewContext>: MotionCoreAnimator {
/// An index of views to their corresponding animator context.
var viewToContexts = [UIView: T]()
/// Cleans the contexts.
override func clean() {
for v in viewToContexts.values {
v.clean()
}
viewToContexts.removeAll()
}
/**
A function that determines if a view can be animated.
- Parameter view: A UIView.
- Parameter isAppearing: A boolean that determines whether the
view is appearing.
*/
override func canAnimate(view: UIView, isAppearing: Bool) -> Bool {
guard let state = context[view] else {
return false
}
return T.canAnimate(view: view, state: state, isAppearing: isAppearing)
}
/**
Animates the fromViews to the toViews.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
- Returns: A TimeInterval.
*/
override func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval {
var d: TimeInterval = 0
for v in fromViews {
createViewContext(view: v, isAppearing: false)
}
for v in toViews {
createViewContext(view: v, isAppearing: true)
}
for v in viewToContexts.values {
if let duration = v.targetState.duration, duration != .infinity {
v.duration = duration
d = max(d, duration)
} else {
let duration = v.snapshot.optimizedDuration(targetState: v.targetState)
if nil == v.targetState.duration {
v.duration = duration
}
d = max(d, duration)
}
}
for v in viewToContexts.values {
if .infinity == v.targetState.duration {
v.duration = d
}
d = max(d, v.startAnimations())
}
return d
}
/**
Moves the view's animation to the given elapsed time.
- Parameter to progress: A TimeInterval.
*/
override func seek(to progress: TimeInterval) {
for v in viewToContexts.values {
v.seek(to: progress)
}
}
/**
Resumes the animation with a given elapsed time and
optional reversed boolean.
- Parameter at progress: A TimeInterval.
- Parameter isReversed: A boolean to reverse the animation
or not.
*/
override func resume(at progress: TimeInterval, isReversed: Bool) -> TimeInterval {
var duration: TimeInterval = 0
for (_, v) in viewToContexts {
if nil == v.targetState.duration {
v.duration = max(v.duration, v.snapshot.optimizedDuration(targetState: v.targetState) + progress)
}
duration = max(duration, v.resume(at: progress, isReversed: isReversed))
}
return duration
}
/**
Applies the given state to the given view.
- Parameter state: A MotionModifier.
- Parameter to view: A UIView.
*/
override func apply(state: MotionTargetState, to view: UIView) {
guard let v = viewToContexts[view] else {
return
}
v.apply(state: state)
}
}
fileprivate extension MotionTargetStateAnimator {
/**
Creates a view context for a given view.
- Parameter view: A UIView.
- Parameter isAppearing: A boolean that determines whether the
view is appearing.
*/
func createViewContext(view: UIView, isAppearing: Bool) {
viewToContexts[view] = T(animator: self, snapshot: context.snapshotView(for: view), targetState: context[view]!, isAppearing: isAppearing)
}
}
...@@ -44,12 +44,12 @@ public final class MotionModifier { ...@@ -44,12 +44,12 @@ public final class MotionModifier {
public extension MotionModifier { public extension MotionModifier {
/** /**
Animates the view with a matching motion identifier. Animates the view with a matching motion identifier.
- Parameter _ identifier: A String. - Parameter _ motionIdentifier: A String.
- Returns: A MotionModifier. - Returns: A MotionModifier.
*/ */
static func motionIdentifier(_ identifier: String) -> MotionModifier { static func source(_ motionIdentifier: String) -> MotionModifier {
return MotionModifier { return MotionModifier {
$0.motionIdentifier = identifier $0.motionIdentifier = motionIdentifier
} }
} }
...@@ -150,10 +150,9 @@ public extension MotionModifier { ...@@ -150,10 +150,9 @@ public extension MotionModifier {
*/ */
static func rotate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> MotionModifier { static func rotate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> MotionModifier {
return MotionModifier { return MotionModifier {
var t = $0.transform ?? CATransform3DIdentity $0.transform = CATransform3DRotate($0.transform ?? CATransform3DIdentity, x, 1, 0, 0)
t = CATransform3DRotate(t, CGFloat(Double.pi) * x / 180, 1, 0, 0) $0.transform = CATransform3DRotate($0.transform!, y, 0, 1, 0)
t = CATransform3DRotate(t, CGFloat(Double.pi) * y / 180, 0, 1, 0) $0.transform = CATransform3DRotate($0.transform!, z, 0, 0, 1)
$0.transform = CATransform3DRotate(t, CGFloat(Double.pi) * z / 180, 0, 0, 1)
} }
} }
...@@ -267,6 +266,17 @@ public extension MotionModifier { ...@@ -267,6 +266,17 @@ public extension MotionModifier {
} }
/** /**
Animates the view's current opacity to the given one.
- Parameter _ opacity: A Double.
- Returns: A MotionModifier.
*/
static func opacity(_ opacity: Double) -> MotionModifier {
return MotionModifier {
$0.opacity = opacity
}
}
/**
Animates the view's current zPosition to the given position. Animates the view's current zPosition to the given position.
- Parameter _ position: An Int. - Parameter _ position: An Int.
- Returns: A MotionModifier. - Returns: A MotionModifier.
...@@ -390,7 +400,9 @@ public extension MotionModifier { ...@@ -390,7 +400,9 @@ public extension MotionModifier {
Sets the view's animation duration to the longest Sets the view's animation duration to the longest
running animation within a transition. running animation within a transition.
*/ */
static var preferredDurationMatchesLongest = MotionModifier.duration(.infinity) static var durationMatchLongest = MotionModifier {
$0.duration = .infinity
}
/** /**
Delays the animation of a given view. Delays the animation of a given view.
...@@ -545,7 +557,7 @@ public extension MotionModifier { ...@@ -545,7 +557,7 @@ public extension MotionModifier {
*/ */
static func beginWith(_ modifiers: [MotionModifier]) -> MotionModifier { static func beginWith(_ modifiers: [MotionModifier]) -> MotionModifier {
return MotionModifier { return MotionModifier {
if $0.beginState == nil { if nil == $0.beginState {
$0.beginState = [] $0.beginState = []
} }
......
...@@ -336,8 +336,8 @@ class TransitionPreprocessor: MotionCorePreprocessor { ...@@ -336,8 +336,8 @@ class TransitionPreprocessor: MotionCorePreprocessor {
} }
#endif #endif
context[tv]!.append(.preferredDurationMatchesLongest) context[tv]!.append(.durationMatchLongest)
context[fv]!.append(.preferredDurationMatchesLongest) context[fv]!.append(.durationMatchLongest)
case .zoom: case .zoom:
context.insertToViewFirst = true context.insertToViewFirst = true
......
...@@ -134,10 +134,10 @@ fileprivate extension MotionTransition { ...@@ -134,10 +134,10 @@ fileprivate extension MotionTransition {
/// Prepares the animators. /// Prepares the animators.
func prepareAnimators() { func prepareAnimators() {
animators = [MotionTargetStateAnimator<MotionCoreAnimationViewContext>()] animators = [MotionCoreAnimator<MotionCoreAnimationViewContext>()]
if #available(iOS 10, tvOS 10, *) { if #available(iOS 10, tvOS 10, *) {
animators.append(MotionTargetStateAnimator<MotionViewPropertyViewContext>()) animators.append(MotionCoreAnimator<MotionViewPropertyViewContext>())
} }
} }
......
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