Reputation: 939
I have seen several examples how to present a custom UIStoryboardSegue
with custom animation. Basically, you subclass UIStoryBoardSegue
and override "perform" method, i.e. like this:
- (void)perform
{
UIViewController *source = self.sourceViewController;
UIViewController *destination = self.destinationViewController;
// Create a UIImage with the contents of the destination
UIGraphicsBeginImageContext(destination.view.bounds.size);
[destination.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *destinationImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Add this image as a subview to the tab bar controller
UIImageView *destinationImageView = [[UIImageView alloc] initWithImage:destinationImage];
[source.parentViewController.view addSubview:destinationImageView];
// Scale the image down and rotate it 180 degrees (upside down)
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(0.1, 0.1);
CGAffineTransform rotateTransform = CGAffineTransformMakeRotation(M_PI);
destinationImageView.transform = CGAffineTransformConcat(scaleTransform, rotateTransform);
// Move the image outside the visible area
CGPoint oldCenter = destinationImageView.center;
CGPoint newCenter = CGPointMake(oldCenter.x - destinationImageView.bounds.size.width, oldCenter.y);
destinationImageView.center = newCenter;
// Start the animation
[UIView animateWithDuration:0.5f
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^(void) {
destinationImageView.transform = CGAffineTransformIdentity;
destinationImageView.center = oldCenter;
}
completion: ^(BOOL done) {
// Remove the image as we no longer need it
[destinationImageView removeFromSuperview];
// Properly present the new screen
[source presentViewController:destination animated:NO completion:nil];
}];
}
But what should I do if I want custom animation while removing Segue from the screen? Override some other method in this class and call it. Or perform animation at the place, where I call "dismissViewController
", which feels not logical?
Will be grateful for the answer,
Artem
Upvotes: 0
Views: 1145
Reputation: 397
To avoid any transformation, here is the code I successfully use (btw answer to Subview has wrong orientation ):
#include <QuartzCore/QuartzCore.h>
@implementation HorizontalSwipingSegue
- (void) perform {
UIViewController *source = self.sourceViewController;
UIViewController *destination = self.destinationViewController;
UIView *sourceView = source.view;
UIView *destinationView = destination.view;
// Create a UIImageView with the contents of the source
UIGraphicsBeginImageContext(sourceView.bounds.size);
[sourceView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *sourceImageView = [[UIImageView alloc] initWithImage:sourceImage];
[[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:NULL];
CGPoint destinationViewFinalCenter = CGPointMake(destinationView.center.x, destinationView.center.y);
CGFloat deltaX = destinationView.frame.size.width;
CGFloat deltaY = destinationView.frame.size.height;
switch (((UIViewController *)self.sourceViewController).interfaceOrientation) {
case UIDeviceOrientationPortrait:
destinationView.center = CGPointMake(destinationView.center.x - deltaX, destinationView.center.y);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
break;
case UIDeviceOrientationPortraitUpsideDown:
destinationView.center = CGPointMake(destinationView.center.x + deltaX, destinationView.center.y);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
break;
case UIDeviceOrientationLandscapeLeft:
destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y - deltaY);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
break;
case UIDeviceOrientationLandscapeRight:
destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y + deltaY);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
break;
}
[destinationView addSubview:sourceImageView];
[UIView animateWithDuration:0.6f
animations:^{
destinationView.center = destinationViewFinalCenter;
}
completion:^(BOOL finished){
[sourceImageView removeFromSuperview];
}];
}
@end
Upvotes: 1
Reputation: 7344
For changing the animation on a dismissViewController
you have to set the modalTransitionStyle
to a UIModalTransitionStyle
on the presentedViewController
.
- (IBAction)dismiss:(id)sender {
self.presentingViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
Upvotes: 1