Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

Commit

Permalink
Add support for interactive transitioning
Browse files Browse the repository at this point in the history
  • Loading branch information
randcode-generator committed Jun 27, 2017
1 parent f643cd5 commit 75bf9aa
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 4 deletions.
7 changes: 7 additions & 0 deletions src/MDMTransition.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <UIKit/UIKit.h>

@protocol MDMTransitionContext;
@protocol MDMInteractiveTransitionContext;

/**
A transition coordinates the animated presentation or dismissal of a view controller.
Expand Down Expand Up @@ -111,3 +112,9 @@ NS_SWIFT_NAME(presentationController(forPresented:presenting:source:));
// clang-format on

@end

NS_SWIFT_NAME(InteractiveTransition)
@protocol MDMInteractiveTransition <NSObject>
- (Boolean)isInteractive:(nonnull id<MDMTransitionContext>)context;
- (void)startWithInteractiveContext:(nonnull id<MDMInteractiveTransitionContext>)context;
@end
10 changes: 10 additions & 0 deletions src/MDMTransitionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ NS_SWIFT_NAME(TransitionContext)
*/
- (void)transitionDidEnd;

@property(nonatomic, readonly) BOOL wasCancelled;

/**
The direction this transition is moving in.
*/
Expand Down Expand Up @@ -84,3 +86,11 @@ NS_SWIFT_NAME(TransitionContext)
*/
@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
2 changes: 1 addition & 1 deletion src/MDMTransitionController.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <Foundation/Foundation.h>

@protocol MDMTransition;
@protocol MDMInteractiveTransition;

/**
A transition controller is a bridge between UIKit's view controller transitioning APIs and
Expand Down Expand Up @@ -44,5 +45,4 @@ NS_SWIFT_NAME(TransitionController)
This may be non-nil while a transition is active.
*/
@property(nonatomic, strong, nullable, readonly) id<MDMTransition> activeTransition;

@end
2 changes: 2 additions & 0 deletions src/UIViewController+TransitionController.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#import <UIKit/UIKit.h>

@protocol MDMTransitionController;
@protocol MDMInteractiveTransitionContext;

@interface UIViewController (MDMTransitionController)

Expand All @@ -32,4 +33,5 @@
@property(nonatomic, strong, readonly, nonnull) id<MDMTransitionController> mdm_transitionController
NS_SWIFT_NAME(transitionController);

@property(nonatomic, strong, nullable) id<MDMInteractiveTransitionContext> interactiveTransitionContext;
@end
10 changes: 10 additions & 0 deletions src/UIViewController+TransitionController.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ @implementation UIViewController (MDMTransitionController)

#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];

Expand Down
40 changes: 40 additions & 0 deletions src/private/MDMPresentationTransitionController.m
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ - (void)setTransition:(id<MDMTransition>)transition {
return _context;
}

- (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id<UIViewControllerAnimatedTransitioning>)animator {
return [self prepareForInteractiveTransition];
}

- (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator {
return [self prepareForInteractiveTransition];
}

// Presentation

- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented
Expand Down Expand Up @@ -129,4 +137,36 @@ - (void)prepareForTransitionWithSourceViewController:(nullable UIViewController
}
}

- (nullable id<UIViewControllerInteractiveTransitioning>)prepareForInteractiveTransition {
Boolean isInteractive = false;

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
2 changes: 1 addition & 1 deletion src/private/MDMViewControllerTransitionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@protocol MDMTransition;
@protocol MDMViewControllerTransitionContextDelegate;

@interface MDMViewControllerTransitionContext : NSObject <MDMTransitionContext, UIViewControllerAnimatedTransitioning>
@interface MDMViewControllerTransitionContext : NSObject <MDMTransitionContext, MDMInteractiveTransitionContext, UIViewControllerAnimatedTransitioning>

- (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition
direction:(MDMTransitionDirection)direction
Expand Down
29 changes: 27 additions & 2 deletions src/private/MDMViewControllerTransitionContext.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@

@implementation MDMViewControllerTransitionContext {
id<UIViewControllerContextTransitioning> _transitionContext;
UIPercentDrivenInteractiveTransition *_percent;
}

@synthesize direction = _direction;
@synthesize sourceViewController = _sourceViewController;
@synthesize backViewController = _backViewController;
@synthesize foreViewController = _foreViewController;
@synthesize presentationController = _presentationController;

@synthesize wasCancelled = _wasCancelled;
- (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition
direction:(MDMTransitionDirection)direction
sourceViewController:(nullable UIViewController *)sourceViewController
Expand All @@ -44,6 +45,7 @@ - (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition
_presentationController = presentationController;

_transition = [self fallbackForTransition:_transition];
_percent = [[UIPercentDrivenInteractiveTransition alloc] init];
}
if (!_transition) {
return nil;
Expand Down Expand Up @@ -82,7 +84,14 @@ - (UIView *)containerView {
}

- (void)transitionDidEnd {
[_transitionContext completeTransition:true];
BOOL wasCanceled = [_transitionContext transitionWasCancelled];
if (wasCanceled) {
_wasCancelled = false;
[_transitionContext completeTransition:false];
} else {
_wasCancelled = true;
[_transitionContext completeTransition:true];
}

_transition = nil;

Expand Down Expand Up @@ -173,4 +182,20 @@ - (void)anticipateOnlyExplicitAnimations {
return transition;
}

- (UIPercentDrivenInteractiveTransition *_Nonnull)getPercentIT {
return _percent;
}

- (void)updatePercent:(CGFloat)percent {
[_percent updateInteractiveTransition:percent];
}

- (void)finishInteractiveTransition {
[_percent finishInteractiveTransition];
}

- (void)cancelInteractiveTransition {
[_percent cancelInteractiveTransition];
}

@end

0 comments on commit 75bf9aa

Please sign in to comment.