gpt4 book ai didi

ios - View Controller 之间的扩展圆圈动画过渡

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:49:54 24 4
gpt4 key购买 nike

我使用转场委托(delegate)创建了自定义动画转场:

vc.modalTransitionStyle = UIModalPresentationCustom;
vc.transitioningDelegate = self.transitioningDelegate;

过渡委托(delegate)工作完美,但我正在尝试实现迄今为止我尚未成功实现的效果。我试图让新的 View Controller 看起来像这样的效果:

Cool animated tranisitoning

我尝试执行 CGAffineTransformMakeScale,但它会缩放新的 View Controller View ,而不仅仅是“将视野扩大到其中”。当尝试用动画改变边界和框架时,它总是在最后适合屏幕边界的圆圈,并没有像我给出的动画中那样完全打开圆圈。

有什么想法吗?

谢谢。

最佳答案

我对这个问题的第一个回答是我之前制作的一个应用程序的修改版本,这不是现在(iOS 7 及更高版本)的最佳方式。在 iOS 7 中,我们可以使用 UIViewControllerTransitioningDelegate 和关联的委托(delegate)和类创建自定义转换。此版本将所有蒙版创建和调整大小封装在动画对象(符合 UIViewControllerAnimatedTransitioning 的对象)中,因此它使 Controller 代码更简单,允许您使用任何 Controller 作为目标 Controller 而无需特殊代码。这是我在进行演示的类(class)中使用的代码,

#import "ViewController.h"
#import "SecondViewController.h"
#import "RDPresentationAnimator.h"

@interface ViewController () <UIViewControllerTransitioningDelegate>
@property (weak,nonatomic) IBOutlet UIButton *button;
@end

@implementation ViewController

-(IBAction)presentSecondController:(UIButton *)sender {
self.button = sender;
SecondViewController *second = [self.storyboard instantiateViewControllerWithIdentifier:@"Second"];
second.modalTransitionStyle = UIModalPresentationCustom;
second.transitioningDelegate = self;
[self presentViewController:second animated:YES completion:nil];
}

-(id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
RDPresentationAnimator *animator = [RDPresentationAnimator new];
animator.isPresenting = YES;
animator.senderFrame = self.button.frame;
return animator;
}


-(id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
NSLog(@"dismissed delegate called");
RDPresentationAnimator *animator = [RDPresentationAnimator new];
animator.isPresenting = NO;
animator.senderFrame = self.button.frame;
return animator;
}

这是动画对象中的代码。 .h,

@interface RDPresentationAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@property (nonatomic) BOOL isPresenting;
@property (nonatomic) CGRect senderFrame;

这是.m,

@interface RDPresentationAnimator ()
@property (strong,nonatomic) UIBezierPath *maskPath;
@property (strong,nonatomic) UIViewController *toVC;
@property (strong,nonatomic) UIViewController *fromVC;
//@property (strong,nonatomic) id <UIViewControllerContextTransitioning> transitionContext;
@end

@implementation RDPresentationAnimator

#define ANIMATION_TIME 0.6



- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
return ANIMATION_TIME;
}


- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
// self.transitionContext = transitionContext;
self.fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
self.toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

if (self.isPresenting) {
[transitionContext.containerView addSubview:self.fromVC.view];
[transitionContext.containerView addSubview:self.toVC.view];

self.maskPath = [UIBezierPath bezierPathWithOvalInRect:self.senderFrame];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.toVC.view.frame;
maskLayer.path = self.maskPath.CGPath;
self.toVC.view.layer.mask = maskLayer;

UIBezierPath *newPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-self.toVC.view.frame.size.width/2, -self.toVC.view.frame.size.height/2, self.toVC.view.frame.size.height*2, self.toVC.view.frame.size.height*2)];
CABasicAnimation* pathAnim = [CABasicAnimation animationWithKeyPath: @"path"];
//pathAnim.delegate = self;
pathAnim.fromValue = (id)self.maskPath.CGPath;
pathAnim.toValue = (id)newPath.CGPath;
pathAnim.duration = ANIMATION_TIME;
maskLayer.path = newPath.CGPath;
[maskLayer addAnimation:pathAnim forKey:@"path"];
}else{
[transitionContext.containerView addSubview:self.toVC.view];
[transitionContext.containerView addSubview:self.fromVC.view];
self.maskPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-self.fromVC.view.frame.size.width/2, -self.fromVC.view.frame.size.height/2, self.fromVC.view.frame.size.height*2, self.fromVC.view.frame.size.height*2)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.fromVC.view.frame;
maskLayer.path = self.maskPath.CGPath;
self.fromVC.view.layer.mask = maskLayer;

UIBezierPath *newPath = [UIBezierPath bezierPathWithOvalInRect:self.senderFrame];
CABasicAnimation* pathAnim = [CABasicAnimation animationWithKeyPath: @"path"];
//pathAnim.delegate = self;
pathAnim.fromValue = (id)self.maskPath.CGPath;
pathAnim.toValue = (id)newPath.CGPath;
pathAnim.duration = ANIMATION_TIME;
maskLayer.path = newPath.CGPath;
[maskLayer addAnimation:pathAnim forKey:@"path"];
}

[self performSelector:@selector(finishTransition:) withObject:transitionContext afterDelay:ANIMATION_TIME];
}



-(void)finishTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
[transitionContext completeTransition:YES];
}


//- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
// NSLog(@"In didStop");
// if (flag) {
// if (self.isPresenting) {
// self.toVC.view.layer.mask = nil;
// [self.transitionContext completeTransition:YES];
// }else{
// self.fromVC.view.layer.mask = nil;
// [self.transitionContext completeTransition:YES];
// self.transitionContext = nil;
// }
// }
//}


-(void)dealloc {
NSLog(@"In animator dealloc");
}

当您关闭模态 Controller 时,此代码还具有反向动画(您只需要调用 dismissViewControllerAnimated:completion: 就像在该类中正常调用一样)。

关于ios - View Controller 之间的扩展圆圈动画过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24705437/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com