blob: 48623c289d75ea0173ff8f49a654e8817fdf3269 [file] [log] [blame] [edit]
// Copyright 2018-present the Material Components for iOS 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.
#import "MDCBottomDrawerTransitionController.h"
#import "MDCBottomDrawerPresentationController.h"
static const NSTimeInterval kOpenAnimationDuration = 0.34;
static const NSTimeInterval kCloseAnimationDuration = 0.3;
static const CGFloat kOpenAnimationSpringDampingRatio = (CGFloat)0.85;
@implementation MDCBottomDrawerTransitionController
#pragma mark UIViewControllerTransitioningDelegate
- (nullable id<UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source {
return self;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:
(UIViewController *)dismissed {
return self;
}
- (UIPresentationController *)
presentationControllerForPresentedViewController:(UIViewController *)presented
presentingViewController:(UIViewController *)presenting
sourceViewController:(UIViewController *)source {
MDCBottomDrawerPresentationController *presentationController =
[[MDCBottomDrawerPresentationController alloc] initWithPresentedViewController:presented
presentingViewController:presenting];
presentationController.trackingScrollView = self.trackingScrollView;
return presentationController;
}
#pragma mark UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:
(nullable id<UIViewControllerContextTransitioning>)transitionContext {
BOOL presenting = [self isPresentingFromContext:transitionContext];
if (presenting) {
return kOpenAnimationDuration;
}
return kCloseAnimationDuration;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
// If a view in the transitionContext is nil, it likely hasn't been loaded by its view controller
// yet. Ask for it directly to initiate a loadView on the ViewController.
UIViewController *fromViewController =
[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
if (fromView == nil) {
fromView = fromViewController.view;
}
UIViewController *toViewController =
[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
if (toView == nil) {
toView = toViewController.view;
}
BOOL presenting = [self isPresentingFromContext:transitionContext];
UIView *animatingView = presenting ? toView : fromView;
UIView *containerView = transitionContext.containerView;
if (presenting) {
[containerView addSubview:animatingView];
CGRect initialFrame = containerView.bounds;
initialFrame.origin.y = CGRectGetHeight(containerView.bounds);
animatingView.frame = initialFrame;
[UIView animateWithDuration:kOpenAnimationDuration
delay:0
usingSpringWithDamping:kOpenAnimationSpringDampingRatio
initialSpringVelocity:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
animatingView.frame = containerView.bounds;
}
completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
} else {
[UIView animateWithDuration:kCloseAnimationDuration
animations:^{
CGRect finalFrame = containerView.bounds;
finalFrame.origin.y = CGRectGetHeight(containerView.bounds);
animatingView.frame = finalFrame;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
[toViewController setNeedsStatusBarAppearanceUpdate];
}];
}
}
- (BOOL)isPresentingFromContext:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController =
[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController =
[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *toPresentingViewController = toViewController.presentingViewController;
return (toPresentingViewController == fromViewController) ? YES : NO;
}
@end