WIP.
diff --git a/examples/CustomPresentationExample.swift b/examples/CustomPresentationExample.swift index c3d3b45..3f1189d 100644 --- a/examples/CustomPresentationExample.swift +++ b/examples/CustomPresentationExample.swift
@@ -250,10 +250,37 @@ } } +private final class DragToDismissInteractionController: NSObject, TransitionInteractionController { + let gestureRecognizer = UIPanGestureRecognizer() + let driver = UIPercentDrivenInteractiveTransition() + var associatedViewController: UIViewController? + + override init() { + super.init() + + self.gestureRecognizer.addTarget(self, action: #selector(didPan(_:))) + } + + func interactionCoordinatorForTransition(with context: TransitionContext) -> UIViewControllerInteractiveTransitioning { + return driver + } + + func didPan(_ gestureRecognizer: UIPanGestureRecognizer) { + switch gestureRecognizer.state { + case .began: + associatedViewController?.dismiss(animated: true) + default: break + } + } +} + extension CustomPresentationExampleViewController { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let modal = ModalViewController() modal.transitionController.transition = transitions[indexPath.row].transition + let interactionController = DragToDismissInteractionController() + modal.view.addGestureRecognizer(interactionController.gestureRecognizer) + modal.transitionController.interactionController = interactionController showDetailViewController(modal, sender: self) } }
diff --git a/src/MDMTransition.h b/src/MDMTransition.h index 3122955..11b0355 100644 --- a/src/MDMTransition.h +++ b/src/MDMTransition.h
@@ -115,8 +115,3 @@ @end -NS_SWIFT_NAME(InteractiveTransition) -@protocol MDMInteractiveTransition <NSObject> -- (Boolean)isInteractive:(nonnull id<MDMTransitionContext>)context; -- (void)startWithInteractiveContext:(nonnull id<MDMInteractiveTransitionContext>)context; -@end
diff --git a/src/MDMTransitionContext.h b/src/MDMTransitionContext.h index 14745ed..4314663 100644 --- a/src/MDMTransitionContext.h +++ b/src/MDMTransitionContext.h
@@ -87,10 +87,3 @@ @property(nonatomic, strong, readonly, nullable) UIPresentationController *presentationController; @end -NS_SWIFT_NAME(InteractiveTransitionContext) -@protocol MDMInteractiveTransitionContext <MDMTransitionContext> -- (UIPercentDrivenInteractiveTransition *_Nonnull)getPercentIT; -- (void)updatePercent:(CGFloat)percent; -- (void)finishInteractiveTransition; -- (void)cancelInteractiveTransition; -@end
diff --git a/src/MDMTransitionController.h b/src/MDMTransitionController.h index e448717..bc54406 100644 --- a/src/MDMTransitionController.h +++ b/src/MDMTransitionController.h
@@ -17,7 +17,7 @@ #import <Foundation/Foundation.h> @protocol MDMTransition; -@protocol MDMInteractiveTransition; +@protocol MDMTransitionInteractionController; /** A transition controller is a bridge between UIKit's view controller transitioning APIs and @@ -45,4 +45,10 @@ This may be non-nil while a transition is active. */ @property(nonatomic, strong, nullable, readonly) id<MDMTransition> activeTransition; + +/** + The interaction controller that will govern any interactions during the transition. + */ +@property(nonatomic, strong, nullable) id<MDMTransitionInteractionController> interactionController; + @end
diff --git a/src/MDMTransitionInteractionController.h b/src/MDMTransitionInteractionController.h new file mode 100644 index 0000000..89a2bbc --- /dev/null +++ b/src/MDMTransitionInteractionController.h
@@ -0,0 +1,30 @@ +/* + Copyright 2017-present The Material Motion Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +@protocol MDMTransitionContext; + +/** + A transition interaction controller is able to control the progress of a transition, often in + reaction to gesture recognition. + */ +NS_SWIFT_NAME(TransitionInteractionController) +@protocol MDMTransitionInteractionController <NSObject> + +@property(nonatomic, weak, nullable) UIViewController *associatedViewController; + +- (nonnull id<UIViewControllerInteractiveTransitioning>)interactionCoordinatorForTransitionWithContext:(nonnull id<MDMTransitionContext>)context; + +@end
diff --git a/src/UIViewController+TransitionController.h b/src/UIViewController+TransitionController.h index 96ae58c..d4fe196 100644 --- a/src/UIViewController+TransitionController.h +++ b/src/UIViewController+TransitionController.h
@@ -33,5 +33,4 @@ @property(nonatomic, strong, readonly, nonnull) id<MDMTransitionController> mdm_transitionController NS_SWIFT_NAME(transitionController); -@property(nonatomic, strong, nullable) id<MDMInteractiveTransitionContext> interactiveTransitionContext; @end
diff --git a/src/UIViewController+TransitionController.m b/src/UIViewController+TransitionController.m index 45d10a9..5f9de4a 100644 --- a/src/UIViewController+TransitionController.m +++ b/src/UIViewController+TransitionController.m
@@ -24,16 +24,6 @@ #pragma mark - Public -- (id<MDMInteractiveTransition>)interactiveTransitionContext { - //const void *key = [self mdm_transitionControllerKey]; - return objc_getAssociatedObject(self, "interactions"); -} - -- (void)setInteractiveTransitionContext:(id<MDMInteractiveTransition>)interactiveTransition { - //const void *key = [self mdm_transitionControllerKey]; - objc_setAssociatedObject(self, "interactions", interactiveTransition, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - - (id<MDMTransitionController>)mdm_transitionController { const void *key = [self mdm_transitionControllerKey];
diff --git a/src/private/MDMPresentationTransitionController.m b/src/private/MDMPresentationTransitionController.m index 102ce12..6fa87fa 100644 --- a/src/private/MDMPresentationTransitionController.m +++ b/src/private/MDMPresentationTransitionController.m
@@ -17,6 +17,7 @@ #import "MDMPresentationTransitionController.h" #import "MDMTransition.h" +#import "MDMTransitionInteractionController.h" #import "MDMViewControllerTransitionContext.h" @interface MDMPresentationTransitionController () <UIViewControllerTransitioningDelegate, MDMViewControllerTransitionContextDelegate> @@ -34,6 +35,7 @@ } @synthesize transition = _transition; +@synthesize interactionController = _interactionController; - (nonnull instancetype)initWithViewController:(nonnull UIViewController *)viewController { self = [super init]; @@ -56,6 +58,12 @@ } } +- (void)setInteractionController:(id<MDMTransitionInteractionController>)interactionController { + _interactionController = interactionController; + + [_interactionController setAssociatedViewController:_associatedViewController]; +} + - (id<MDMTransition>)activeTransition { return _context.transition; } @@ -85,11 +93,13 @@ } - (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id<UIViewControllerAnimatedTransitioning>)animator { - return [self prepareForInteractiveTransition]; + [self prepareForInteractiveTransition]; + return [_interactionController interactionCoordinatorForTransitionWithContext:_context]; } - (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator { - return [self prepareForInteractiveTransition]; + [self prepareForInteractiveTransition]; + return [_interactionController interactionCoordinatorForTransitionWithContext:_context]; } // Presentation @@ -137,36 +147,8 @@ } } -- (nullable id<UIViewControllerInteractiveTransitioning>)prepareForInteractiveTransition { - Boolean isInteractive = false; +- (void)prepareForInteractiveTransition { - Boolean isInteractiveResponds = false; - Boolean startWithInteractiveResponds = false; - - if ([_transition respondsToSelector:@selector(isInteractive:)]) { - isInteractiveResponds = true; - } else { - return nil; - } - - if ([_transition respondsToSelector:@selector(startWithInteractiveContext:)]) { - startWithInteractiveResponds = true; - } else { - return nil; - } - - if (isInteractiveResponds && startWithInteractiveResponds) { - id<MDMInteractiveTransition> interactiveTransition = (id<MDMInteractiveTransition>)_transition; - isInteractive = [interactiveTransition isInteractive:_context]; - if (isInteractive) { - [interactiveTransition startWithInteractiveContext:_context]; - } - } - - UIPercentDrivenInteractiveTransition *pdi = [_context getPercentIT]; - // Setting the completion speed to a value close to 1.0 prevents - // the bar from sometimes jumping. - pdi.completionSpeed = 0.933; - return isInteractive == false ? nil : pdi; } + @end
diff --git a/src/private/MDMViewControllerTransitionContext.h b/src/private/MDMViewControllerTransitionContext.h index 396ebb3..e6f75db 100644 --- a/src/private/MDMViewControllerTransitionContext.h +++ b/src/private/MDMViewControllerTransitionContext.h
@@ -21,7 +21,7 @@ @protocol MDMTransition; @protocol MDMViewControllerTransitionContextDelegate; -@interface MDMViewControllerTransitionContext : NSObject <MDMTransitionContext, MDMInteractiveTransitionContext, UIViewControllerAnimatedTransitioning> +@interface MDMViewControllerTransitionContext : NSObject <MDMTransitionContext, UIViewControllerAnimatedTransitioning> - (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition direction:(MDMTransitionDirection)direction
diff --git a/src/private/MDMViewControllerTransitionContext.m b/src/private/MDMViewControllerTransitionContext.m index 7900270..d6a5c90 100644 --- a/src/private/MDMViewControllerTransitionContext.m +++ b/src/private/MDMViewControllerTransitionContext.m
@@ -20,7 +20,6 @@ @implementation MDMViewControllerTransitionContext { id<UIViewControllerContextTransitioning> _transitionContext; - UIPercentDrivenInteractiveTransition *_percent; } @synthesize direction = _direction; @@ -29,6 +28,7 @@ @synthesize foreViewController = _foreViewController; @synthesize presentationController = _presentationController; @synthesize wasCancelled = _wasCancelled; + - (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition direction:(MDMTransitionDirection)direction sourceViewController:(nullable UIViewController *)sourceViewController @@ -48,7 +48,6 @@ if (!_transition) { return nil; } - _percent = [[UIPercentDrivenInteractiveTransition alloc] init]; } return self; } @@ -69,10 +68,6 @@ [self initiateTransition]; } -// TODO(featherless): Implement interactive transitioning. Need to implement -// UIViewControllerInteractiveTransitioning here and isInteractive and interactionController* in -// MDMPresentationTransitionController. - #pragma mark - MDMTransitionContext - (NSTimeInterval)duration { @@ -182,20 +177,4 @@ return transition; } -- (UIPercentDrivenInteractiveTransition *_Nonnull)getPercentIT { - return _percent; -} - -- (void)updatePercent:(CGFloat)percent { - [_percent updateInteractiveTransition:percent]; -} - -- (void)finishInteractiveTransition { - [_percent finishInteractiveTransition]; -} - -- (void)cancelInteractiveTransition { - [_percent cancelInteractiveTransition]; -} - @end