From 12acff94e9d0070014c41dd39a7083d57dd4ff5f Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Tue, 16 May 2017 11:32:10 -0400 Subject: [PATCH] Add support for fallback transitions. Summary: This new API allows transitions to fallback to other transition types in certain contexts. For example, a full-screen fab transition might choose to fall back to a modal slide transition when being dismissed. In order to check sameness we had to make Transition a class protocol. This doesn't affect any existing transition implementations because they are all classes in practice. Reviewers: O2 Material Motion, O4 Material Apple platform reviewers, #material_motion, randcode-generator Reviewed By: randcode-generator Tags: #material_motion Differential Revision: http://codereview.cc/D3228 --- src/transitions/Transition.swift | 16 +++++++++++++++- src/transitions/TransitionContext.swift | 8 ++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/transitions/Transition.swift b/src/transitions/Transition.swift index e6646d0..9bcf89d 100644 --- a/src/transitions/Transition.swift +++ b/src/transitions/Transition.swift @@ -21,7 +21,7 @@ import UIKit A transition is responsible for describing the motion that will occur during a UIViewController transition. */ -public protocol Transition { +public protocol Transition: class { /** Invoked on initiation of a view controller transition. @@ -30,6 +30,20 @@ public protocol Transition { func willBeginTransition(withContext ctx: TransitionContext, runtime: MotionRuntime) -> [Stateful] } +/** + A transition can return an alternative fallback transition instance. + */ +public protocol TransitionWithFallback: Transition { + /** + Invoked before the transition begins. + + If the returned instance also conforms to TransitionWithFallback, then the returned instance's + fallback will be queried. This repeats until a returned instance does not conform to + TransitionWithFallback or it returns self. + */ + func fallbackTansition(withContext ctx: TransitionContext) -> Transition +} + /** A transition is responsible for describing the motion that will occur during a UIViewController transition. diff --git a/src/transitions/TransitionContext.swift b/src/transitions/TransitionContext.swift index 4895ffe..37cd120 100644 --- a/src/transitions/TransitionContext.swift +++ b/src/transitions/TransitionContext.swift @@ -111,6 +111,14 @@ public final class TransitionContext: NSObject { self.transition = transition super.init() + + while let fallbackTransition = self.transition as? TransitionWithFallback { + let fallback = fallbackTransition.fallbackTansition(withContext: self) + if fallback === self.transition { + break + } + self.transition = fallback + } } fileprivate let initialDirection: TransitionDirection