使用自定义动画删除自定义 UIStoryboardSegue
Posted
技术标签:
【中文标题】使用自定义动画删除自定义 UIStoryboardSegue【英文标题】:Remove custom UIStoryboardSegue with custom animation 【发布时间】:2012-10-26 08:12:05 【问题描述】:我已经看到了几个如何使用自定义动画呈现自定义UIStoryboardSegue
的示例。基本上,您将UIStoryBoardSegue
子类化并覆盖“执行”方法,即像这样:
- (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];
];
但是如果我想要自定义动画同时从屏幕上移除 Segue,我该怎么办?覆盖这个类中的一些其他方法并调用它。或者在我叫“dismissViewController
”的地方做动画,感觉不合逻辑?
不胜感激,
阿尔乔姆
【问题讨论】:
【参考方案1】:要更改dismissViewController
上的动画,您必须将presentedViewController
上的modalTransitionStyle
设置为UIModalTransitionStyle
。
- (IBAction)dismiss:(id)sender
self.presentingViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
【讨论】:
tnx 的答案,但我问我应该创建动画的地方。当我呈现一个视图(模态或推送)时,我在 perform 方法中执行它,但是当我想解除它时,我通常在父代理中调用dismissViewController,它是在那里创建动画的合适位置吗? 好的,现在我看到你的意见了。但是在 Segue 子类中设置当前动画并在 VC 类中关闭动画是否是一种好习惯,您怎么看? 据我所知,关闭 viewController 时没有其他可能性。如果需要,您可以使用相同的技术来呈现视图控制器。缺点是没有做一些技巧就没有自定义动画的选项。 但我认为对于自定义动画,您可以使用与我的示例代码相同的技巧。没试过,但我认为应该可以。【参考方案2】:为避免任何转换,这是我成功使用的代码(顺便说一句,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
【讨论】:
谢谢你的回答,我想我做的有点类似以上是关于使用自定义动画删除自定义 UIStoryboardSegue的主要内容,如果未能解决你的问题,请参考以下文章
使用 UIStoryBoard 基于自定义 URL 方案处理屏幕
UIStoryboard 中的自定义原型单元已创建,但未显示在 UITableView
自定义 UINavigationItem 类 - 标题取决于 Active UIStoryboard