Commit 936c5b62 by Daniel Dahan

reworked IgnoreSubviewTransitionsPreprocessor

parent b6de5705
......@@ -20,8 +20,6 @@
96AEB68E1EE4610F009A3BE0 /* MotionCoreAnimationViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB6661EE4610F009A3BE0 /* MotionCoreAnimationViewContext.swift */; };
96AEB68F1EE4610F009A3BE0 /* MotionDefaultAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB6671EE4610F009A3BE0 /* MotionDefaultAnimator.swift */; };
96AEB6901EE4610F009A3BE0 /* MotionViewPropertyViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB6681EE4610F009A3BE0 /* MotionViewPropertyViewContext.swift */; };
96AEB6911EE4610F009A3BE0 /* MotionDebugPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB66A1EE4610F009A3BE0 /* MotionDebugPlugin.swift */; };
96AEB6921EE4610F009A3BE0 /* MotionDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB66B1EE4610F009A3BE0 /* MotionDebugView.swift */; };
96AEB6931EE4610F009A3BE0 /* TransitionPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB66C1EE4610F009A3BE0 /* TransitionPreprocessor.swift */; };
96AEB6941EE4610F009A3BE0 /* Motion+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB66E1EE4610F009A3BE0 /* Motion+Array.swift */; };
96AEB6951EE4610F009A3BE0 /* Motion+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AEB66F1EE4610F009A3BE0 /* Motion+CALayer.swift */; };
......@@ -58,8 +56,6 @@
96AEB6661EE4610F009A3BE0 /* MotionCoreAnimationViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionCoreAnimationViewContext.swift; sourceTree = "<group>"; };
96AEB6671EE4610F009A3BE0 /* MotionDefaultAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionDefaultAnimator.swift; sourceTree = "<group>"; };
96AEB6681EE4610F009A3BE0 /* MotionViewPropertyViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionViewPropertyViewContext.swift; sourceTree = "<group>"; };
96AEB66A1EE4610F009A3BE0 /* MotionDebugPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionDebugPlugin.swift; sourceTree = "<group>"; };
96AEB66B1EE4610F009A3BE0 /* MotionDebugView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionDebugView.swift; sourceTree = "<group>"; };
96AEB66C1EE4610F009A3BE0 /* TransitionPreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TransitionPreprocessor.swift; path = ../TransitionPreprocessor.swift; sourceTree = "<group>"; };
96AEB66E1EE4610F009A3BE0 /* Motion+Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Motion+Array.swift"; sourceTree = "<group>"; };
96AEB66F1EE4610F009A3BE0 /* Motion+CALayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Motion+CALayer.swift"; sourceTree = "<group>"; };
......@@ -112,15 +108,6 @@
path = Animator;
sourceTree = "<group>";
};
96AEB6691EE4610F009A3BE0 /* Debug Plugin */ = {
isa = PBXGroup;
children = (
96AEB66A1EE4610F009A3BE0 /* MotionDebugPlugin.swift */,
96AEB66B1EE4610F009A3BE0 /* MotionDebugView.swift */,
);
path = "Debug Plugin";
sourceTree = "<group>";
};
96AEB66D1EE4610F009A3BE0 /* Extensions */ = {
isa = PBXGroup;
children = (
......@@ -184,7 +171,6 @@
96E49A3F1EEA08F8006D5A93 /* MotionTransitionObserver.swift */,
96AEB67D1EE4610F009A3BE0 /* MotionPlugin.swift */,
96AEB6641EE4610F009A3BE0 /* Animator */,
96AEB6691EE4610F009A3BE0 /* Debug Plugin */,
96AEB66D1EE4610F009A3BE0 /* Extensions */,
96AEB6861EE4610F009A3BE0 /* Preprocessors */,
);
......@@ -286,7 +272,6 @@
96AEB6941EE4610F009A3BE0 /* Motion+Array.swift in Sources */,
96AEB6951EE4610F009A3BE0 /* Motion+CALayer.swift in Sources */,
96AEB68E1EE4610F009A3BE0 /* MotionCoreAnimationViewContext.swift in Sources */,
96AEB6921EE4610F009A3BE0 /* MotionDebugView.swift in Sources */,
96E49A401EEA08F8006D5A93 /* MotionTransitionObserver.swift in Sources */,
96AEB6A01EE4610F009A3BE0 /* MotionIndependentController.swift in Sources */,
966A7F091EEC422000A2DAAC /* MotionSnapshotType.swift in Sources */,
......@@ -298,7 +283,6 @@
96AEB6AE1EE4610F009A3BE0 /* IgnoreSubviewModifiersPreprocessor.swift in Sources */,
96AEB68D1EE4610F009A3BE0 /* MotionAnimatorViewContext.swift in Sources */,
96AEB6B01EE4610F009A3BE0 /* SourcePreprocessor.swift in Sources */,
96AEB6911EE4610F009A3BE0 /* MotionDebugPlugin.swift in Sources */,
963150D21EE50DA6002B0D42 /* Motion+Obj-C.swift in Sources */,
96AEB6AF1EE4610F009A3BE0 /* MatchPreprocessor.swift in Sources */,
96AEB69E1EE4610F009A3BE0 /* MotionController.swift in Sources */,
......
/*
* 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
#if os(iOS)
public class MotionDebugPlugin: MotionPlugin {
public static var showOnTop: Bool = false
var debugView: MotionDebugView?
var zPositionMap = [UIView: CGFloat]()
var addedLayers: [CALayer] = []
var updating = false
override public func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval {
if Motion.shared.forceNonInteractive { return 0 }
var hasArc = false
for v in context.fromViews + context.toViews where context[v]?.arc != nil && context[v]?.position != nil {
hasArc = true
break
}
let debugView = MotionDebugView(initialProcess: Motion.shared.isPresenting ? 0.0 : 1.0, showCurveButton:hasArc, showOnTop:MotionDebugPlugin.showOnTop)
debugView.frame = Motion.shared.container.bounds
debugView.delegate = self
UIApplication.shared.keyWindow!.addSubview(debugView)
debugView.layoutSubviews()
self.debugView = debugView
UIView.animate(withDuration: 0.4) {
debugView.showControls = true
}
return .infinity
}
public override func resume(at: TimeInterval, isReversed: Bool) -> TimeInterval {
guard let debugView = debugView else { return 0.4 }
debugView.delegate = nil
UIView.animate(withDuration: 0.4) {
debugView.showControls = false
debugView.debugSlider.setValue(roundf(debugView.progress), animated: true)
}
on3D(wants3D: false)
return 0.4
}
public override func clean() {
debugView?.removeFromSuperview()
debugView = nil
}
}
extension MotionDebugPlugin:MotionDebugViewDelegate {
public func onDone() {
guard let debugView = debugView else { return }
let seekValue = Motion.shared.isPresenting ? debugView.progress : 1.0 - debugView.progress
if seekValue > 0.5 {
Motion.shared.end()
} else {
Motion.shared.cancel()
}
}
public func onProcessSliderChanged(progress: Float) {
let seekValue = Motion.shared.isPresenting ? progress : 1.0 - progress
Motion.shared.update(elapsedTime: Double(seekValue))
}
func onPerspectiveChanged(translation: CGPoint, rotate: CGFloat, scale: CGFloat) {
var t = CATransform3DIdentity
t.m34 = -1 / 4000
t = CATransform3DTranslate(t, translation.x, translation.y, 0)
t = CATransform3DScale(t, scale, scale, 1)
t = CATransform3DRotate(t, rotate, 0, 1, 0)
Motion.shared.container.layer.sublayerTransform = t
}
func animateZPosition(view: UIView, to: CGFloat) {
let a = CABasicAnimation(keyPath: "zPosition")
a.fromValue = view.layer.value(forKeyPath: "zPosition")
a.toValue = NSNumber(value: Double(to))
a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
a.duration = 0.4
view.layer.add(a, forKey: "zPosition")
view.layer.zPosition = to
}
func onDisplayArcCurve(wantsCurve: Bool) {
for layer in addedLayers {
layer.removeFromSuperlayer()
addedLayers.removeAll()
}
if wantsCurve {
for layer in Motion.shared.container.layer.sublayers! {
for (_, anim) in layer.animations {
if let keyframeAnim = anim as? CAKeyframeAnimation, let path = keyframeAnim.path {
let s = CAShapeLayer()
s.zPosition = layer.zPosition + 10
s.path = path
s.strokeColor = UIColor.blue.cgColor
s.fillColor = UIColor.clear.cgColor
Motion.shared.container.layer.addSublayer(s)
addedLayers.append(s)
}
}
}
}
}
func on3D(wants3D: Bool) {
var t = CATransform3DIdentity
if wants3D {
var viewsWithZPosition = Set<UIView>()
for view in Motion.shared.container.subviews where view.layer.zPosition != 0 {
viewsWithZPosition.insert(view)
zPositionMap[view] = view.layer.zPosition
}
let viewsWithoutZPosition = Motion.shared.container.subviews.filter { return !viewsWithZPosition.contains($0) }
let viewsWithPositiveZPosition = viewsWithZPosition.filter { return $0.layer.zPosition > 0 }
for (i, v) in viewsWithoutZPosition.enumerated() {
animateZPosition(view:v, to:CGFloat(i * 10))
}
var maxZPosition: CGFloat = 0
for v in viewsWithPositiveZPosition {
maxZPosition = max(maxZPosition, v.layer.zPosition)
animateZPosition(view:v, to:v.layer.zPosition + CGFloat(viewsWithoutZPosition.count * 10))
}
t.m34 = -1 / 4000
t = CATransform3DTranslate(t, debugView!.translation.x, debugView!.translation.y, 0)
t = CATransform3DScale(t, debugView!.scale, debugView!.scale, 1)
t = CATransform3DRotate(t, debugView!.rotate, 0, 1, 0)
} else {
for v in Motion.shared.container.subviews {
animateZPosition(view:v, to:self.zPositionMap[v] ?? 0)
}
self.zPositionMap.removeAll()
}
let a = CABasicAnimation(keyPath: "sublayerTransform")
a.fromValue = Motion.shared.container.layer.value(forKeyPath: "sublayerTransform")
a.toValue = NSValue(caTransform3D: t)
a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
a.duration = 0.4
UIView.animate(withDuration:0.4) {
self.context.container.backgroundColor = UIColor(white: 0.85, alpha: 1.0)
}
Motion.shared.container.layer.add(a, forKey: "debug")
Motion.shared.container.layer.sublayerTransform = t
}
}
#endif
/*
* 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
#if os(iOS)
protocol MotionDebugViewDelegate: class {
func onProcessSliderChanged(progress: Float)
func onPerspectiveChanged(translation: CGPoint, rotate: CGFloat, scale: CGFloat)
func on3D(wants3D: Bool)
func onDisplayArcCurve(wantsCurve: Bool)
func onDone()
}
class MotionDebugView: UIView {
var backgroundView: UIView!
var debugSlider: UISlider!
var perspectiveButton: UIButton!
var doneButton: UIButton!
var arcCurveButton: UIButton?
weak var delegate: MotionDebugViewDelegate?
var panGR: UIPanGestureRecognizer!
var pinchGR: UIPinchGestureRecognizer!
var showControls: Bool = false {
didSet {
layoutSubviews()
}
}
var showOnTop: Bool = false
var rotate: CGFloat = .pi / 6
var scale: CGFloat = 0.6
var translation: CGPoint = .zero
var progress: Float {
return debugSlider.value
}
init(initialProcess: Float, showCurveButton: Bool, showOnTop: Bool) {
super.init(frame:.zero)
self.showOnTop = showOnTop
backgroundView = UIView(frame:.zero)
backgroundView.backgroundColor = UIColor(white: 1.0, alpha: 0.95)
backgroundView.layer.shadowColor = UIColor.darkGray.cgColor
backgroundView.layer.shadowOpacity = 0.3
backgroundView.layer.shadowRadius = 5
backgroundView.layer.shadowOffset = CGSize.zero
addSubview(backgroundView)
doneButton = UIButton(type: .system)
doneButton.setTitle("Done", for: .normal)
doneButton.addTarget(self, action: #selector(onDone), for: .touchUpInside)
backgroundView.addSubview(doneButton)
perspectiveButton = UIButton(type: .system)
perspectiveButton.setTitle("3D View", for: .normal)
perspectiveButton.addTarget(self, action: #selector(onPerspective), for: .touchUpInside)
backgroundView.addSubview(perspectiveButton)
if showCurveButton {
arcCurveButton = UIButton(type: .system)
arcCurveButton!.setTitle("Show Arcs", for: .normal)
arcCurveButton!.addTarget(self, action: #selector(onDisplayArcCurve), for: .touchUpInside)
backgroundView.addSubview(arcCurveButton!)
}
debugSlider = UISlider(frame: .zero)
debugSlider.layer.zPosition = 1000
debugSlider.minimumValue = 0
debugSlider.maximumValue = 1
debugSlider.addTarget(self, action: #selector(onSlide), for: .valueChanged)
debugSlider.isUserInteractionEnabled = true
debugSlider.value = initialProcess
backgroundView.addSubview(debugSlider)
panGR = UIPanGestureRecognizer(target: self, action: #selector(pan))
panGR.delegate = self
panGR.maximumNumberOfTouches = 1
addGestureRecognizer(panGR)
pinchGR = UIPinchGestureRecognizer(target: self, action: #selector(pinch))
pinchGR.delegate = self
addGestureRecognizer(pinchGR)
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func layoutSubviews() {
super.layoutSubviews()
var backgroundFrame = bounds
backgroundFrame.size.height = 72
if showOnTop {
backgroundFrame.origin.y = showControls ? 0 : -80
} else {
backgroundFrame.origin.y = bounds.maxY - CGFloat(showControls ? 72.0 : -8.0)
}
backgroundView.frame = backgroundFrame
var sliderFrame = bounds.insetBy(dx: 10, dy: 0)
sliderFrame.size.height = 44
sliderFrame.origin.y = 28
debugSlider.frame = sliderFrame
perspectiveButton.sizeToFit()
perspectiveButton.frame.origin = CGPoint(x:bounds.maxX - perspectiveButton.bounds.width - 10, y: 4)
doneButton.sizeToFit()
doneButton.frame.origin = CGPoint(x:10, y: 4)
arcCurveButton?.sizeToFit()
arcCurveButton?.center = CGPoint(x: center.x, y: doneButton.center.y)
}
var startRotation: CGFloat = 0
@objc public func pan() {
if panGR.state == .began {
startRotation = rotate
}
rotate = startRotation + panGR.translation(in: nil).x / 150
if rotate > .pi {
rotate -= 2 * .pi
} else if rotate < -.pi {
rotate += 2 * .pi
}
delegate?.onPerspectiveChanged(translation:translation, rotate: rotate, scale:scale)
}
var startLocation: CGPoint = .zero
var startTranslation: CGPoint = .zero
var startScale: CGFloat = 1
@objc public func pinch() {
switch pinchGR.state {
case .began:
startLocation = pinchGR.location(in: nil)
startTranslation = translation
startScale = scale
fallthrough
case .changed:
if pinchGR.numberOfTouches >= 2 {
scale = min(1, max(0.2, startScale * pinchGR.scale))
translation = startTranslation + pinchGR.location(in: nil) - startLocation
delegate?.onPerspectiveChanged(translation:translation, rotate: rotate, scale:scale)
}
default:
break
}
}
@objc public func onDone() {
delegate?.onDone()
}
@objc public func onPerspective() {
perspectiveButton.isSelected = !perspectiveButton.isSelected
delegate?.on3D(wants3D: perspectiveButton.isSelected)
}
@objc public func onDisplayArcCurve() {
arcCurveButton!.isSelected = !arcCurveButton!.isSelected
delegate?.onDisplayArcCurve(wantsCurve: arcCurveButton!.isSelected)
}
@objc public func onSlide() {
delegate?.onProcessSliderChanged(progress: debugSlider.value)
}
}
extension MotionDebugView:UIGestureRecognizerDelegate {
public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return perspectiveButton.isSelected
}
}
#endif
......@@ -470,7 +470,7 @@ fileprivate extension MotionController {
/// Prepares the preprocessors.
func preparePreprocessors() {
preprocessors = [
IgnoreSubviewModifiersPreprocessor(),
IgnoreSubviewTransitionsPreprocessor(),
MatchPreprocessor(),
SourcePreprocessor(),
CascadePreprocessor(),
......
......@@ -56,12 +56,12 @@ open class MotionPlugin: NSObject, MotionPreprocessor, MotionAnimator {
To check a view's transitions:
context[view]
context[view, "modifierName"]
context[view, "transitionName"]
To set a view's transitions:
context[view] = [("modifier1", ["parameter1"]), ("modifier2", [])]
context[view, "modifier1"] = ["parameter1", "parameter2"]
context[view] = [("transition1", ["parameter1"]), ("transition2", [])]
context[view, "transition1"] = ["parameter1", "parameter2"]
*/
open func process(fromViews: [UIView], toViews: [UIView]) {}
......
......@@ -520,7 +520,7 @@ extension MotionTransition {
that appear differently than the actual view.
In that case, use .useNormalSnapshot or .useSlowRenderSnapshot to disable the optimization.
This modifier actually does nothing by itself since .useOptimizedSnapshot is the default.
This transition actually does nothing by itself since .useOptimizedSnapshot is the default.
*/
public static var useOptimizedSnapshot = MotionTransition {
$0.snapshotType = .optimized
......
......@@ -65,7 +65,7 @@ class CascadePreprocessor: MotionPreprocessor {
weak var context: MotionContext!
/**
Processes the from-views and to-views.
Processes the transitionary views.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
......@@ -84,8 +84,7 @@ class CascadePreprocessor: MotionPreprocessor {
continue
}
var parentView = v is UITableView ? v.subviews.get(0) ?? v : v
let parentView = v is UITableView ? v.subviews.get(0) ?? v : v
let sortedSubviews = parentView.subviews.sorted(by: direction.comparator)
let initialDelay = context[v]!.delay
......
......@@ -33,7 +33,7 @@ class DurationPreprocessor: MotionPreprocessor {
weak var context: MotionContext!
/**
Implementation for processor.
Processes the transitionary views.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
......
......@@ -28,37 +28,54 @@
import UIKit
class IgnoreSubviewModifiersPreprocessor: MotionPreprocessor {
class IgnoreSubviewTransitionsPreprocessor: MotionPreprocessor {
/// A reference to a MotionContext.
weak var context: MotionContext!
/**
Processes the transitionary views.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
func process(fromViews: [UIView], toViews: [UIView]) {
process(views:fromViews)
process(views:toViews)
}
/**
Process an Array of views for the cascade animation.
- Parameter views: An Array of UIViews.
*/
func process(views: [UIView]) {
for view in views {
guard let recursive = context[view]?.ignoreSubviewTransitions else { continue }
var parentView = view
if view is UITableView, let wrapperView = view.subviews.get(0) {
parentView = wrapperView
for v in views {
guard let recursive = context[v]?.ignoreSubviewTransitions else {
continue
}
if recursive {
cleanSubviewModifiers(parentView)
} else {
let parentView = v is UITableView ? v.subviews.get(0) ?? v : v
guard recursive else {
for subview in parentView.subviews {
context[subview] = nil
}
continue
}
cleanSubviewTransitions(for: parentView)
}
}
}
private func cleanSubviewModifiers(_ parentView: UIView) {
for view in parentView.subviews {
context[view] = nil
cleanSubviewModifiers(view)
extension IgnoreSubviewTransitionsPreprocessor {
/**
Clears the transition for a given view's subviews.
- Parameter for view: A UIView.
*/
fileprivate func cleanSubviewTransitions(for view: UIView) {
for v in view.subviews {
context[v] = nil
cleanSubviewTransitions(for: v)
}
}
}
......@@ -188,36 +188,7 @@ class TransitionPreprocessor: MotionPreprocessor {
}
/**
Shifts the transition by a given size.
- Parameter direction: A MotionTransitionType.Direction.
- Parameter isAppearing: A boolean indicating whether it is appearing
or not.
- Parameter size: An optional CGSize.
- Parameter transpose: A boolean indicating to change the `x` point for `y`
and `y` point for `x`.
- Returns: A CGPoint.
*/
func shift(direction: MotionTransitionType.Direction, isAppearing: Bool, size: CGSize? = nil, transpose: Bool = false) -> CGPoint {
let size = size ?? context.container.bounds.size
let point: CGPoint
switch direction {
case .left, .right:
point = CGPoint(x: (.right == direction) == isAppearing ? -size.width : size.width, y: 0)
case .up, .down:
point = CGPoint(x: 0, y: (.down == direction) == isAppearing ? -size.height : size.height)
}
if transpose {
return CGPoint(x: point.y, y: point.x)
}
return point
}
/**
Implementation for processor.
Processes the transitionary views.
- Parameter fromViews: An Array of UIViews.
- Parameter toViews: An Array of UIViews.
*/
......@@ -376,4 +347,33 @@ class TransitionPreprocessor: MotionPreprocessor {
fatalError("Not implemented")
}
}
/**
Shifts the transition by a given size.
- Parameter direction: A MotionTransitionType.Direction.
- Parameter isAppearing: A boolean indicating whether it is appearing
or not.
- Parameter size: An optional CGSize.
- Parameter transpose: A boolean indicating to change the `x` point for `y`
and `y` point for `x`.
- Returns: A CGPoint.
*/
func shift(direction: MotionTransitionType.Direction, isAppearing: Bool, size: CGSize? = nil, transpose: Bool = false) -> CGPoint {
let size = size ?? context.container.bounds.size
let point: CGPoint
switch direction {
case .left, .right:
point = CGPoint(x: (.right == direction) == isAppearing ? -size.width : size.width, y: 0)
case .up, .down:
point = CGPoint(x: 0, y: (.down == direction) == isAppearing ? -size.height : size.height)
}
if transpose {
return CGPoint(x: point.y, y: point.x)
}
return point
}
}
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