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

Add support for interactive transitioning #14

Closed

Conversation

randcode-generator
Copy link
Contributor

#3

@codecov
Copy link

codecov bot commented Jun 6, 2017

Codecov Report

Merging #14 into develop will decrease coverage by 15.66%.
The diff coverage is 21.15%.

Impacted file tree graph

@@             Coverage Diff              @@
##           develop      #14       +/-   ##
============================================
- Coverage    80.13%   64.46%   -15.67%     
============================================
  Files            3        4        +1     
  Lines          146      197       +51     
============================================
+ Hits           117      127       +10     
- Misses          29       70       +41
Impacted Files Coverage Δ
...te/MDMViewControllerInteractiveTransitionContext.m 0% <0%> (ø)
src/UIViewController+TransitionController.m 76% <0%> (-24%) ⬇️
src/private/MDMPresentationTransitionController.m 61.33% <24%> (-18.67%) ⬇️
src/private/MDMViewControllerTransitionContext.m 74.69% <71.42%> (-0.63%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 10daa68...3c1d297. Read the comment docs.

Copy link
Contributor

@jverkoey jverkoey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass at feedback.

}
timer.resume()
}
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a new example and include this timer code there so that users can play with the demo more easily.

var i = 0.01
func start(withInteractiveContext context: InteractiveTransitionContext) {
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .milliseconds(10), leeway: .milliseconds(10))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember: transition instances are reused for both the present and dismiss transitions, so any instance variables need to be re-initialized before the transition begins. In this case, we need to remember to reset i to 0.01 when we start the interactive transition.

If we don't reset the i value then the transition will immediately complete the dismissal transition.

});
dispatch_resume(timer);
}
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above: let's create a new example that specifically demonstrates interactive transitioning.

@@ -34,6 +35,8 @@ NS_SWIFT_NAME(Transition)
*/
- (void)startWithContext:(nonnull id<MDMTransitionContext>)context;

@optional
- (void)startWithInteractiveContext:(nonnull id<MDMInteractiveTransitionContext>)context;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally prefer avoiding @optional these days because it means the compiler won't enforce method signatures.

Instead, I suggest we add an MDMTransitionWithInteraction protocol similar to how we've been building the other features.

@@ -80,3 +80,9 @@ NS_SWIFT_NAME(TransitionContext)
@property(nonatomic, strong, readonly, nonnull) UIView *containerView;

@end

NS_SWIFT_NAME(InteractiveTransitionContext)
@protocol MDMInteractiveTransitionContext
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this conform to MDMTransitionContext?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made MDMInteractiveTransitionContext because this controls how much of the animation should be presented. The MDMTransitionContext controls what animation should be presented.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means the interactive start API won't have access to things like the container view, the transition's direction, or the fore/back view controller - is this intentional? I can imagine that someone might want to have access to those properties in order to be able to configure the interactive behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean someone changing the animation midway?
For example,
1 second (total) animation of view fading in. Around 0.5 seconds into the animation, user can also manipulate the size of view.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might want to parse gestural movement differently depending on whether the transition is moving forward or backward, for example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking in here again: were you able to try making this conform to MDMTransitionContext?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't tried. I'll try it now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I have to admit this doesn't make any sense to me.
So right now, I have

@property(nonatomic, readonly, nonnull) id<MDMTransitionContext> transitionContext;

to save the instance of MDMTransitionContext. If I inherit it, all I am doing is adding wrappers around MDMTransitionContext and I still have to save the instance so I can implement transitionDidEnd.

Copy link
Contributor

@jverkoey jverkoey Jun 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a checklist below, but in short you shouldn't have to save the transition context in any sense because we already have a transition context - you'll provide this same instance to both the transition and the interactive transition (i.e. the transition interaction controller).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like you want interactive transition and transition merged. So, I'll check if isInteractive is implemented. If it's not implemented, I assume it's not interactive, if it is implemented, I'll call isInteractive to determine if the direction (forward/backward) should be interactive.


if ([_transition respondsToSelector:@selector(startWithInteractiveContext:)]) {
_interactiveContext = [[MDMViewControllerInteractiveTransitionContext alloc] initWithTransition: _transition];
[_transition startWithInteractiveContext:_interactiveContext];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we'd put the animated and interactive start invocations alongside one another in the transition context instance. Is it possible to move this call there?

@randcode-generator randcode-generator force-pushed the issue3 branch 8 times, most recently from 8cce24b to b9ea0c3 Compare June 13, 2017 03:56
@@ -80,3 +80,9 @@ NS_SWIFT_NAME(TransitionContext)
@property(nonatomic, strong, readonly, nonnull) UIView *containerView;

@end

NS_SWIFT_NAME(InteractiveTransitionContext)
@protocol MDMInteractiveTransitionContext
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking in here again: were you able to try making this conform to MDMTransitionContext?

@jverkoey
Copy link
Contributor

jverkoey commented Jun 16, 2017

Am proposing the following changes to consolidate the code paths here (these affect public APIs which is why I'm suggesting we make these changes now before the code lands):

  • Make MDMInteractiveTransitionContext conform to TransitionContext.
  • Delete transitionContext from InteractiveTransitionContext.
  • Rename InteractiveTransition to TransitionInteractionController.
  • Delete ViewControllerInteractiveTransitionContext and implement InteractiveTransitionContext in ViewControllerInteractiveTransitionContext.
  • Provide the transition context instance to both the Transition and TransitionInteractionController. Transition will receive a TransitionContext. TransitionInteractionController will receive an InteractiveTransitionContext.


NS_SWIFT_NAME(InteractiveTransition)
@protocol MDMInteractiveTransition <NSObject>
- (Boolean)isInteractive:(nonnull id<MDMTransitionContext>)context;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BOOL

@@ -44,5 +45,5 @@ NS_SWIFT_NAME(TransitionController)
This may be non-nil while a transition is active.
*/
@property(nonatomic, strong, nullable, readonly) id<MDMTransition> activeTransition;

@property(nonatomic, strong, nullable) id<MDMInteractiveTransition> interactiveTransition;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This technically isn't a "transition" as much as an interaction controller for a transition. Can we consider renaming this to transitionInteractionController?

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

@property(nonatomic, strong, nullable) id<MDMInteractiveTransitionContext> interactiveTransitionContext;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to expose this if we store the variable on the transition controller.

transitionController.transition = CrossFade()
transitionController.transitionInteractionController = SwipeToDismiss()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the type for transitionInteractionController?

@@ -129,4 +144,35 @@ - (void)prepareForTransitionWithSourceViewController:(nullable UIViewController
}
}

- (nullable id<UIViewControllerInteractiveTransitioning>) prepareForInteractiveTransition {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this method would happen as a result of prepareForTransition. We know that the animation callback is invoked first and therefor our transition context will be initialized, so we can return the percent-driven transition controller from our transition context.

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants