认定animation类似于在iOS 7中打开应用程序:viewcontroller框架不能resize

我愿意创build一个类似于在iOS 7中打开应用程序的segueanimation。现在我考虑这种方法: 非segue的实现 ,但遇到了一个问题:如果在自定义segue中实现,代码无法调整viewcontroller的框架,这是主animation的一部分。 正如我所看到的,它适用于viewcontroller的位置,但不能改变它的大小。 我是否正确,该属性viewcontroller.view.frame不能animation,必须保持不变,等于设备的屏幕大小? 我已经实现了与CGAffineTransformMakeScale类似的东西,但它CGAffineTransformMakeScale ,所以,我正在寻找更好的解决scheme。 下面我粘贴我用于segue的代码。

 #import "ZoomSegue.h" #import "MiniMapViewController.h" #import "InteractiveMapViewController.h" @implementation ZoomSegue - (void)perform { InteractiveMapViewController *sourceViewController = self.sourceViewController; MiniMapViewController *destinationViewController = self.destinationViewController; destinationViewController.view.alpha = 0.0f; destinationViewController.view.hidden = NO; //Just to check, lets make view really small. Position it to the center we get from the segue. destinationViewController.view.frame = CGRectMake(_originatingPoint.x, _originatingPoint.y, 60.0f, 60.0f); [sourceViewController.view addSubview:destinationViewController.view]; float animationDuration = 1.5f; [UIView animateWithDuration:animationDuration/2.0f animations:^{ destinationViewController.view.alpha = 1.0f; }]; [UIView animateWithDuration:animationDuration animations:^{ //Just to check, lets make view very big. It does not work, although, the view goes to the upper left corner, so position works, but not the size CGRect x = CGRectMake(0.0f, 0.0f, 9590.0f, 91366.0f); destinationViewController.view.frame = x; }]; } @end 

我不知道你是否正确,但无论如何,更好的方法是使用快照视图。 这段代码将一个小快照放在屏幕的中心,然后将其展开为全尺寸,

 - (void)perform { UIView *sourceView = ((UIViewController *)self.sourceViewController).view; UIView *destinationView = [((UIViewController *)self.destinationViewController).view snapshotViewAfterScreenUpdates:YES]; destinationView.frame = CGRectMake(0, 0, 5, 5); destinationView.center = CGPointMake(sourceView.center.x, sourceView.center.y); [sourceView addSubview:destinationView]; [UIView animateWithDuration:1 animations:^{ destinationView.frame = sourceView.frame; } completion:^(BOOL finished) { [[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:nil]; }]; } 

编辑后:

以下是您提供的链接中的代码翻译,将该animation转换为细分,

 -(void)perform { CGFloat duration = .25; UIViewController *source = self.sourceViewController; UIView *bg = [source.view snapshotViewAfterScreenUpdates:YES]; bg.frame = UIScreen.mainScreen.bounds; UIViewController *dest = self.destinationViewController; UIView *icon = [dest.view snapshotViewAfterScreenUpdates:YES]; icon.frame = self.iconFrame; icon.alpha = 0.0f; [source.view addSubview:bg]; [source.view addSubview:icon]; [UIView animateWithDuration:duration animations:^{ icon.alpha = 1.0f; }]; [UIView animateWithDuration:duration*2 animations:^{ icon.frame = UIScreen.mainScreen.bounds; bg.frame = [self zoomedRect]; } completion:^(BOOL finished) { [source presentViewController:dest animated:NO completion:nil]; [bg removeFromSuperview]; [icon removeFromSuperview]; }]; } - (CGRect)zoomedRect { float screenWidth = UIScreen.mainScreen.bounds.size.width; float screenHeight = UIScreen.mainScreen.bounds.size.height; float size = screenWidth / self.iconFrame.size.width; float x = screenWidth/2 - (CGRectGetMidX(self.iconFrame) * size); float y = screenHeight/2 - (CGRectGetMidY(self.iconFrame) * size); return CGRectMake(x, y, screenWidth * size, screenHeight * size); } 

我有一个CGREct属性,在segue的.h文件中的iconFrame。 我从一个连接到将被展开的图标的轻击手势识别器中执行了这个segue。 您需要将该图标的框架传递给segue,我在源视图控制器的prepareForSegue方法中执行此操作,

 -(void)prepareForSegue:(SpringboardSegue *)segue sender:(UITapGestureRecognizer *)sender { segue.iconFrame = sender.view.frame; } 

我在SWIFT中翻译了相同的代码。

 class CustomOpenSegue: UIStoryboardSegue { var iconFrame = CGRect() override func perform(){ var sourceViewController: UIViewController = self.sourceViewController as UIViewController var bg:UIView = sourceViewController.view.snapshotViewAfterScreenUpdates(true) bg.frame = UIScreen.mainScreen().bounds var destinationViewController: UIViewController = self.destinationViewController as UIViewController var icon:UIView = destinationViewController.view.snapshotViewAfterScreenUpdates(true) icon.frame = self.iconFrame icon.alpha = 0.0 sourceViewController.view.addSubview(icon) UIView.animateWithDuration(0.25, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { icon.alpha = 1.0 }, completion: nil ) UIView.animateWithDuration(0.5, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in icon.frame = UIScreen.mainScreen().bounds bg.frame = self.zoomedRect }) { (finished) -> Void in sourceViewController.navigationController?.pushViewController(destinationViewController, animated: false) icon.removeFromSuperview() bg.removeFromSuperview() } } var zoomedRect:CGRect{ var screenWidth = UIScreen.mainScreen().bounds.size.width var screenHeight = UIScreen.mainScreen().bounds.size.height var size = screenWidth / self.iconFrame.size.width var x = screenWidth / 2 - CGRectGetMidX(self.iconFrame) * size var y = screenHeight / 2 - CGRectGetMidY(self.iconFrame) * size return CGRectMake(x, y, screenWidth * size, screenHeight * size) } } 

这就是你所说的:

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue is CustomOpenSegue{ let customOpenSegue = segue as CustomOpenSegue customOpenSegue.iconFrame = self.mapButtonFrame! } }