Skip to content

Commit 1beb425

Browse files
Add support for interactive transitioning
material-motion#3
1 parent cb620f1 commit 1beb425

9 files changed

+160
-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.
@@ -88,3 +89,9 @@ NS_SWIFT_NAME(presentationController(forPresented:presenting:source:));
8889
// clang-format on
8990

9091
@end
92+
93+
NS_SWIFT_NAME(InteractiveTransition)
94+
@protocol MDMInteractiveTransition <NSObject>
95+
- (Boolean)isInteractive:(nonnull id<MDMTransitionContext>)context;
96+
- (void)startWithInteractiveContext:(nonnull id<MDMInteractiveTransitionContext>)context;
97+
@end

src/MDMTransitionContext.h

+9
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,12 @@ NS_SWIFT_NAME(TransitionContext)
8080
@property(nonatomic, strong, readonly, nonnull) UIView *containerView;
8181

8282
@end
83+
84+
NS_SWIFT_NAME(InteractiveTransitionContext)
85+
@protocol MDMInteractiveTransitionContext
86+
- (void)updatePercent:(CGFloat)percent;
87+
- (void)finishInteractiveTransition;
88+
- (void)cancelInteractiveTransition;
89+
90+
@property(nonatomic, readonly, nonnull) id<MDMTransitionContext> transitionContext;
91+
@end

src/MDMTransitionController.h

+2-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
@@ -37,5 +38,5 @@ NS_SWIFT_NAME(TransitionController)
3738
`modalPresentationStyle` property.
3839
*/
3940
@property(nonatomic, strong, nullable) id<MDMTransition> transition;
40-
41+
@property(nonatomic, strong, nullable) id<MDMInteractiveTransition> interactiveTransition;
4142
@end

src/UIViewController+TransitionController.h

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

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

2122
@interface UIViewController (MDMTransitionController)
2223

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

35+
@property(nonatomic, strong, nullable) id<MDMInteractiveTransitionContext> interactiveTransitionContext;
3436
@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, key);
30+
}
31+
32+
- (void)setInteractiveTransitionContext:(id<MDMInteractiveTransition>) interactiveTransition {
33+
const void *key = [self mdm_transitionControllerKey];
34+
objc_setAssociatedObject(self, key, interactiveTransition, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
35+
}
36+
2737
- (id<MDMTransitionController>)mdm_transitionController {
2838
const void *key = [self mdm_transitionControllerKey];
2939

src/private/MDMPresentationTransitionController.m

+46
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import "MDMPresentationTransitionController.h"
1818

1919
#import "MDMTransition.h"
20+
#import "MDMViewControllerInteractiveTransitionContext.h"
2021
#import "MDMViewControllerTransitionContext.h"
2122

2223
@interface MDMPresentationTransitionController () <UIViewControllerTransitioningDelegate, MDMViewControllerTransitionContextDelegate>
@@ -30,10 +31,12 @@ @implementation MDMPresentationTransitionController {
3031
UIPresentationController *_presentationController;
3132

3233
MDMViewControllerTransitionContext *_context;
34+
MDMViewControllerInteractiveTransitionContext *_interactiveContext;
3335
__weak UIViewController *_source;
3436
}
3537

3638
@synthesize transition = _transition;
39+
@synthesize interactiveTransition = _interactiveTransition;
3740

3841
- (nonnull instancetype)initWithViewController:(nonnull UIViewController *)viewController {
3942
self = [super init];
@@ -56,6 +59,10 @@ - (void)setTransition:(id<MDMTransition>)transition {
5659
}
5760
}
5861

62+
- (void)setInteractiveTransition:(id<MDMInteractiveTransition>)transition {
63+
_interactiveTransition = transition;
64+
}
65+
5966
#pragma mark - UIViewControllerTransitioningDelegate
6067

6168
// Animated transitions
@@ -80,6 +87,14 @@ - (void)setTransition:(id<MDMTransition>)transition {
8087
return _context;
8188
}
8289

90+
- (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id<UIViewControllerAnimatedTransitioning>)animator {
91+
return [self prepareForInteractiveTransition];
92+
}
93+
94+
- (nullable id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator {
95+
return [self prepareForInteractiveTransition];
96+
}
97+
8398
// Presentation
8499

85100
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented
@@ -125,4 +140,35 @@ - (void)prepareForTransitionWithSourceViewController:(nullable UIViewController
125140
}
126141
}
127142

143+
- (nullable id<UIViewControllerInteractiveTransitioning>) prepareForInteractiveTransition {
144+
Boolean isInteractive = false;
145+
146+
if (_interactiveTransition) {
147+
Boolean isInteractiveResponds = false;
148+
Boolean startWithInteractiveResponds = false;
149+
150+
if ([_interactiveTransition respondsToSelector:@selector(isInteractive:)]) {
151+
isInteractiveResponds = true;
152+
} else {
153+
return nil;
154+
}
155+
156+
if ([_interactiveTransition respondsToSelector:@selector(startWithInteractiveContext:)]) {
157+
startWithInteractiveResponds = true;
158+
} else {
159+
return nil;
160+
}
161+
162+
if(isInteractiveResponds && startWithInteractiveResponds) {
163+
isInteractive = [_interactiveTransition isInteractive:_context];
164+
if(isInteractive) {
165+
_interactiveContext = [[MDMViewControllerInteractiveTransitionContext alloc] initWithTransition:_context];
166+
167+
[_interactiveTransition startWithInteractiveContext:_interactiveContext];
168+
}
169+
}
170+
}
171+
172+
return isInteractive == false ? nil : [_interactiveContext getPercentIT];
173+
}
128174
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import <Foundation/Foundation.h>
18+
#import "MDMTransition.h"
19+
#import "MDMTransitionContext.h"
20+
#import "MDMViewControllerTransitionContext.h"
21+
22+
@interface MDMViewControllerInteractiveTransitionContext : NSObject <MDMInteractiveTransitionContext>
23+
- (nonnull instancetype)initWithTransition:(nonnull id<MDMTransitionContext>)transitionContext;
24+
- (UIPercentDrivenInteractiveTransition* _Nonnull)getPercentIT;
25+
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright 2017-present The Material Motion Authors. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#import "MDMViewControllerInteractiveTransitionContext.h"
18+
19+
@implementation MDMViewControllerInteractiveTransitionContext {
20+
UIPercentDrivenInteractiveTransition *_percent;
21+
}
22+
23+
@synthesize transitionContext = _transitionContext;
24+
25+
- (nonnull instancetype)initWithTransition:(nonnull id<MDMTransitionContext>)transitionContext {
26+
self = [super init];
27+
if (self) {
28+
_percent = [[UIPercentDrivenInteractiveTransition alloc] init];
29+
_transitionContext = transitionContext;
30+
}
31+
return self;
32+
}
33+
34+
- (UIPercentDrivenInteractiveTransition *_Nonnull)getPercentIT {
35+
return _percent;
36+
}
37+
38+
- (void)updatePercent:(CGFloat)percent {
39+
[_percent updateInteractiveTransition:percent];
40+
}
41+
42+
- (void)finishInteractiveTransition {
43+
[_percent finishInteractiveTransition];
44+
}
45+
46+
- (void)cancelInteractiveTransition {
47+
[_percent cancelInteractiveTransition];
48+
}
49+
@end

src/private/MDMViewControllerTransitionContext.m

+10-3
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,18 @@ - (UIView *)containerView {
7878
}
7979

8080
- (void)transitionDidEnd {
81-
[_transitionContext completeTransition:true];
82-
81+
BOOL wasCanceled = [_transitionContext transitionWasCancelled];
82+
if(wasCanceled) {
83+
[_transitionContext completeTransition: false];
84+
} else {
85+
[_transitionContext completeTransition: true];
86+
}
87+
8388
_transition = nil;
8489

85-
[_delegate transitionDidCompleteWithContext:self];
90+
if(!wasCanceled) {
91+
[_delegate transitionDidCompleteWithContext:self];
92+
}
8693
}
8794

8895
#pragma mark - Private

0 commit comments

Comments
 (0)