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

Commit 320d7f9

Browse files
Add support for interactive transitioning
#3
1 parent f643cd5 commit 320d7f9

8 files changed

+98
-4
lines changed

src/MDMTransition.h

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import <UIKit/UIKit.h>
1818

1919
@protocol MDMTransitionContext;
20+
@protocol MDMInteractiveTransitionContext;
2021

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

113114
@end
115+
116+
NS_SWIFT_NAME(InteractiveTransition)
117+
@protocol MDMInteractiveTransition <NSObject>
118+
- (Boolean)isInteractive:(nonnull id<MDMTransitionContext>)context;
119+
- (void)startWithInteractiveContext:(nonnull id<MDMInteractiveTransitionContext>)context;
120+
@end

src/MDMTransitionContext.h

+10
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ NS_SWIFT_NAME(TransitionContext)
4343
*/
4444
- (void)transitionDidEnd;
4545

46+
@property(nonatomic, readonly) BOOL wasCancelled;
47+
4648
/**
4749
The direction this transition is moving in.
4850
*/
@@ -84,3 +86,11 @@ NS_SWIFT_NAME(TransitionContext)
8486
*/
8587
@property(nonatomic, strong, readonly, nullable) UIPresentationController *presentationController;
8688
@end
89+
90+
NS_SWIFT_NAME(InteractiveTransitionContext)
91+
@protocol MDMInteractiveTransitionContext <MDMTransitionContext>
92+
- (UIPercentDrivenInteractiveTransition *_Nonnull)getPercentIT;
93+
- (void)updatePercent:(CGFloat)percent;
94+
- (void)finishInteractiveTransition;
95+
- (void)cancelInteractiveTransition;
96+
@end

src/MDMTransitionController.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import <Foundation/Foundation.h>
1818

1919
@protocol MDMTransition;
20+
@protocol MDMInteractiveTransition;
2021

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

src/UIViewController+TransitionController.h

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#import <UIKit/UIKit.h>
1919

2020
@protocol MDMTransitionController;
21+
@protocol MDMInteractiveTransitionContext;
2122

2223
@interface UIViewController (MDMTransitionController)
2324

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

36+
@property(nonatomic, strong, nullable) id<MDMInteractiveTransitionContext> interactiveTransitionContext;
3537
@end

src/UIViewController+TransitionController.m

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ @implementation UIViewController (MDMTransitionController)
2424

2525
#pragma mark - Public
2626

27+
- (id<MDMInteractiveTransition>)interactiveTransitionContext {
28+
//const void *key = [self mdm_transitionControllerKey];
29+
return objc_getAssociatedObject(self, "interactions");
30+
}
31+
32+
- (void)setInteractiveTransitionContext:(id<MDMInteractiveTransition>)interactiveTransition {
33+
//const void *key = [self mdm_transitionControllerKey];
34+
objc_setAssociatedObject(self, "interactions", interactiveTransition, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
35+
}
36+
2737
- (id<MDMTransitionController>)mdm_transitionController {
2838
const void *key = [self mdm_transitionControllerKey];
2939

src/private/MDMPresentationTransitionController.m

+40
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ - (void)setTransition:(id<MDMTransition>)transition {
8484
return _context;
8585
}
8686

87+
- (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id<UIViewControllerAnimatedTransitioning>)animator {
88+
return [self prepareForInteractiveTransition];
89+
}
90+
91+
- (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator {
92+
return [self prepareForInteractiveTransition];
93+
}
94+
8795
// Presentation
8896

8997
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented
@@ -129,4 +137,36 @@ - (void)prepareForTransitionWithSourceViewController:(nullable UIViewController
129137
}
130138
}
131139

140+
- (nullable id<UIViewControllerInteractiveTransitioning>)prepareForInteractiveTransition {
141+
Boolean isInteractive = false;
142+
143+
Boolean isInteractiveResponds = false;
144+
Boolean startWithInteractiveResponds = false;
145+
146+
if ([_transition respondsToSelector:@selector(isInteractive:)]) {
147+
isInteractiveResponds = true;
148+
} else {
149+
return nil;
150+
}
151+
152+
if ([_transition respondsToSelector:@selector(startWithInteractiveContext:)]) {
153+
startWithInteractiveResponds = true;
154+
} else {
155+
return nil;
156+
}
157+
158+
if (isInteractiveResponds && startWithInteractiveResponds) {
159+
id<MDMInteractiveTransition> interactiveTransition = (id<MDMInteractiveTransition>)_transition;
160+
isInteractive = [interactiveTransition isInteractive:_context];
161+
if (isInteractive) {
162+
[interactiveTransition startWithInteractiveContext:_context];
163+
}
164+
}
165+
166+
UIPercentDrivenInteractiveTransition *pdi = [_context getPercentIT];
167+
// Setting the completion speed to a value close to 1.0 prevents
168+
// the bar from sometimes jumping.
169+
pdi.completionSpeed = 0.933;
170+
return isInteractive == false ? nil : pdi;
171+
}
132172
@end

src/private/MDMViewControllerTransitionContext.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
@protocol MDMTransition;
2222
@protocol MDMViewControllerTransitionContextDelegate;
2323

24-
@interface MDMViewControllerTransitionContext : NSObject <MDMTransitionContext, UIViewControllerAnimatedTransitioning>
24+
@interface MDMViewControllerTransitionContext : NSObject <MDMTransitionContext, MDMInteractiveTransitionContext, UIViewControllerAnimatedTransitioning>
2525

2626
- (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition
2727
direction:(MDMTransitionDirection)direction

src/private/MDMViewControllerTransitionContext.m

+27-2
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020

2121
@implementation MDMViewControllerTransitionContext {
2222
id<UIViewControllerContextTransitioning> _transitionContext;
23+
UIPercentDrivenInteractiveTransition *_percent;
2324
}
2425

2526
@synthesize direction = _direction;
2627
@synthesize sourceViewController = _sourceViewController;
2728
@synthesize backViewController = _backViewController;
2829
@synthesize foreViewController = _foreViewController;
2930
@synthesize presentationController = _presentationController;
30-
31+
@synthesize wasCancelled = _wasCancelled;
3132
- (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition
3233
direction:(MDMTransitionDirection)direction
3334
sourceViewController:(nullable UIViewController *)sourceViewController
@@ -44,6 +45,7 @@ - (nonnull instancetype)initWithTransition:(nonnull id<MDMTransition>)transition
4445
_presentationController = presentationController;
4546

4647
_transition = [self fallbackForTransition:_transition];
48+
_percent = [[UIPercentDrivenInteractiveTransition alloc] init];
4749
}
4850
if (!_transition) {
4951
return nil;
@@ -82,7 +84,14 @@ - (UIView *)containerView {
8284
}
8385

8486
- (void)transitionDidEnd {
85-
[_transitionContext completeTransition:true];
87+
BOOL wasCanceled = [_transitionContext transitionWasCancelled];
88+
if (wasCanceled) {
89+
_wasCancelled = false;
90+
[_transitionContext completeTransition:false];
91+
} else {
92+
_wasCancelled = true;
93+
[_transitionContext completeTransition:true];
94+
}
8695

8796
_transition = nil;
8897

@@ -173,4 +182,20 @@ - (void)anticipateOnlyExplicitAnimations {
173182
return transition;
174183
}
175184

185+
- (UIPercentDrivenInteractiveTransition *_Nonnull)getPercentIT {
186+
return _percent;
187+
}
188+
189+
- (void)updatePercent:(CGFloat)percent {
190+
[_percent updateInteractiveTransition:percent];
191+
}
192+
193+
- (void)finishInteractiveTransition {
194+
[_percent finishInteractiveTransition];
195+
}
196+
197+
- (void)cancelInteractiveTransition {
198+
[_percent cancelInteractiveTransition];
199+
}
200+
176201
@end

0 commit comments

Comments
 (0)