// _____ _
// |_ _| |_ _ _ ___ ___ _ __ __ _
// | | | ' \| '_/ -_) -_) ' \/ _` |_
// |_| |_||_|_| \___\___|_|_|_\__,_(_)
//
// Threema iOS Client
// Copyright (c) 2015-2020 Threema GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
#import "FullScreenImageTransitionAnimator.h"
#import "FullscreenImageViewController.h"
#import "GroupDetailsViewController.h"
#import "ContactDetailsViewController.h"
#import "MyIdentityViewController.h"
#import "ContactsViewController.h"
#import "Threema-Swift.h"
@interface FullScreenImageTransitionAnimator ()
@property NSTimeInterval duration;
@end
@implementation FullScreenImageTransitionAnimator
- (instancetype)init
{
self = [super init];
if (self) {
_duration = 0.4f;
}
return self;
}
#pragma mark - UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:(id)transitionContext {
return _duration;
}
- (void)animateTransition:(id)transitionContext
{
if ([transitionContext isAnimated] == NO) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
return;
}
// Setup for animation transition
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
if ([fromVC isKindOfClass:[FullscreenImageViewController class]] && [toVC isKindOfClass:[GroupDetailsViewController class]]) {
GroupDetailsViewController *gVC = (GroupDetailsViewController *)toVC;
[self animateImage:(FullscreenImageViewController *)fromVC toImageVC:gVC view:gVC.imageView context:transitionContext];
} else if ([fromVC isKindOfClass:[GroupDetailsViewController class]] && [toVC isKindOfClass:[FullscreenImageViewController class]]) {
GroupDetailsViewController *gVC = (GroupDetailsViewController *)fromVC;
[self animateFromVC:gVC toImageVC:(FullscreenImageViewController *)toVC view:gVC.imageView context:transitionContext];
} else if ([fromVC isKindOfClass:[FullscreenImageViewController class]] && [toVC isKindOfClass:[ContactDetailsViewController class]]) {
ContactDetailsViewController *cVC = (ContactDetailsViewController *)toVC;
[self animateImage:(FullscreenImageViewController *)fromVC toImageVC:cVC view:cVC.imageView context:transitionContext];
} else if ([fromVC isKindOfClass:[ContactDetailsViewController class]] && [toVC isKindOfClass:[FullscreenImageViewController class]]) {
ContactDetailsViewController *cVC = (ContactDetailsViewController *)fromVC;
[self animateFromVC:cVC toImageVC:(FullscreenImageViewController *)toVC view:cVC.imageView context:transitionContext];
} else if ([fromVC isKindOfClass:[FullscreenImageViewController class]] && [toVC isKindOfClass:[MeContactDetailsViewController class]]) {
MeContactDetailsViewController *gVC = (MeContactDetailsViewController *)toVC;
[self animateImage:(FullscreenImageViewController *)fromVC toImageVC:gVC view:gVC.imageView context:transitionContext];
} else if ([fromVC isKindOfClass:[MeContactDetailsViewController class]] && [toVC isKindOfClass:[FullscreenImageViewController class]]) {
MeContactDetailsViewController *gVC = (MeContactDetailsViewController *)fromVC;
[self animateFromVC:gVC toImageVC:(FullscreenImageViewController *)toVC view:gVC.imageView context:transitionContext];
}
else if ([fromVC isKindOfClass:[FullscreenImageViewController class]] && [toVC isKindOfClass:[ContactsViewController class]]) {
ContactsViewController *cVC = (ContactsViewController *)toVC;
[self animateImage:(FullscreenImageViewController *)fromVC toImageVC:cVC view:cVC.segmentedControl context:transitionContext];
}
else {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}
}
- (void)animateImage:(FullscreenImageViewController *)imageVC toImageVC:(UIViewController *)presentingVC view:(UIView *)view context:(id)transitionContext {
UIView *containerView = [transitionContext containerView];
UIImageView *animatedView = [imageVC createImageView];
CGRect finalRect = [transitionContext finalFrameForViewController:presentingVC];
CGRect destRect = [presentingVC.view convertRect:view.frame fromView:view.superview];
destRect = CGRectOffset(destRect, 0.0, finalRect.origin.y);
CGRect srcRect = [containerView convertRect:animatedView.frame fromView:imageVC.view];
[containerView addSubview:presentingVC.view];
presentingVC.view.alpha = 0.0;
animatedView.alpha = 1.0;
animatedView.frame = srcRect;
[containerView addSubview:animatedView];
[UIView animateWithDuration:_duration delay:0.0 usingSpringWithDamping:0.75 initialSpringVelocity:0.0 options:0 animations:^{
animatedView.frame = destRect;
animatedView.alpha = 0.0;
presentingVC.view.alpha = 1.0;
} completion:^(BOOL finished) {
[animatedView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (void)animateFromVC:(UIViewController *)presentingVC toImageVC:(FullscreenImageViewController *)imageVC view:(UIView *)view context:(id)transitionContext {
UIView *containerView = [transitionContext containerView];
UIImageView *animatedView = [imageVC createImageView];
[containerView addSubview:presentingVC.view];
CGRect finalRect = [transitionContext finalFrameForViewController:imageVC];
animatedView.frame = CGRectOffset(animatedView.frame, 0.0, finalRect.origin.y);
CGRect srcRect = [containerView convertRect:view.frame fromView:view.superview];
CGRect destRect = animatedView.frame;
UIView *bgView = [[UIView alloc] initWithFrame:containerView.bounds];
bgView.backgroundColor = imageVC.view.backgroundColor;
bgView.alpha = 0.0;
[containerView addSubview:bgView];
animatedView.alpha = 0.0;
animatedView.frame = srcRect;
[containerView addSubview:animatedView];
[UIView animateWithDuration:_duration delay:0.0 usingSpringWithDamping:0.75 initialSpringVelocity:0.0 options:0 animations:^{
animatedView.frame = destRect;
animatedView.alpha = 1.0;
bgView.alpha = 1.0;
presentingVC.view.alpha = 0.0;
} completion:^(BOOL finished) {
[containerView addSubview:imageVC.view];
[animatedView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end