实现自定义动画以在iPad上显示指定视图的模态视图

Zeb*_*ebs 25 iphone animation ipad modalviewcontroller ios

在iPad上我们有更多的工作空间,因此呈现全屏模态视图并不理想.

我知道如何在新的formSheet中呈现模态视图,并且可以在这个问题上找到一个接近的方法:iPad iTunes动画

问题是你无法选择动画的来源,所以它只是默认并从中心出现,我想自定义它以便从特定位置出现.

我可以在此视频的前几秒看到这个动画的最佳例子

如果有人能够使用代码,教程或文档指出我正确的方向,我将非常感谢!

更新:

经过一番调查后,我发现第一部分可以使用图层和核心动画来完成; 然后动画一个formSheet模态视图,但我仍然不太明白如何实现它,希望你们可以帮助!

Mih*_*atu 21

我所做的是为UIViewController创建一个新类别,如下所示

的UIViewController + ShowModalFromView.h

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

@interface UIViewController (ShowModalFromView)

- (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view;

@end
Run Code Online (Sandbox Code Playgroud)

的UIViewController + ShowModalFromView.m

#import "UIViewController+ShowModalFromView.h"

@implementation UIViewController (ShowModalFromView)

- (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view
{
    modalViewController.modalPresentationStyle = UIModalPresentationFormSheet;

    // Add the modal viewController but don't animate it. We will handle the animation manually
    [self presentModalViewController:modalViewController animated:NO];

    // Remove the shadow. It causes weird artifacts while animating the view.
    CGColorRef originalShadowColor = modalViewController.view.superview.layer.shadowColor;
    modalViewController.view.superview.layer.shadowColor = [[UIColor clearColor] CGColor];

    // Save the original size of the viewController's view    
    CGRect originalFrame = modalViewController.view.superview.frame;

    // Set the frame to the one of the view we want to animate from
    modalViewController.view.superview.frame = view.frame;

    // Begin animation
    [UIView animateWithDuration:1.0f
                     animations:^{
                         // Set the original frame back
                         modalViewController.view.superview.frame = originalFrame;
                     }
                     completion:^(BOOL finished) {
                         // Set the original shadow color back after the animation has finished
                         modalViewController.view.superview.layer.shadowColor = originalShadowColor;
                     }];
}

@end
Run Code Online (Sandbox Code Playgroud)

这很直接.如果这有助于您,请告诉我.

UPDATE

我已经更新了使用动画块而不是[UIView beginAnimations:nil context:nil];/ [UIView commitAnimations]pair 的答案.

  • 这实际上是一个很好的解决方案 不过,我在使用UIModalPresentationFullScreen时遇到了问题.我得到一个黑屏,然后动画开始,视图完全显示. (2认同)

小智 5

看起来你基本上是在翻译(移动)一段CALayer时间后缩小它并同时围绕y轴旋转它.试试这个:

NSValue *initialTransformValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
CATransform3D translation = CATransform3DMakeTranslation(finalPoint.x, finalPoint.y, 0.0);
CATransform3D scalingAndTranslation = CATransform3DScale(translation, kMyScalingFactor, kMyScalingFactor, 1.0);
CATransform3D finalTransform = CATransform3DRotate(scalingAndTranslation, myRotationAngle, 0.0, 1.0, 0.0);
NSArray *keyFrameValues = [NSArray arrayWithObjects:initialTransformValue, [NSValue valueWithCATransform3D:finalTransform], nil];
CAKeyframeAnimation *myAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
myAnimation.values = keyFrameValues;
myAnimation.duration = kMyAnimationDuration;
myAnimation.delegate = self;
myAnimation.removedOnCompletion = NO;
myAnimation.fillMode = kCAFillModeForwards;
[myLayer addAnimation:myAnimation forKey:@"myAnimationKey"];
Run Code Online (Sandbox Code Playgroud)
  • finalPoint应该是CGPoint 在坐标空间中myLayer.
  • kMyScalingFactor 按比例缩小<1.0,按比例缩小> 1.0.
  • myRotationAngle应该是弧度.使用正值旋转顺时针和负值逆时针旋转.

您还需要实现动画终止处理程序以使动画"粘贴":

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    myLayer.transform = finalTransform;
    myLayer removeAnimationForKey:@"myAnimationKey"];
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.