- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我使用转场委托(delegate)创建了自定义动画转场:
vc.modalTransitionStyle = UIModalPresentationCustom;
vc.transitioningDelegate = self.transitioningDelegate;
过渡委托(delegate)工作完美,但我正在尝试实现迄今为止我尚未成功实现的效果。我试图让新的 View Controller 看起来像这样的效果:
我尝试执行 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/
Yii::$app->runAction('new_controller/new_action', $params); 我相信这可以用来从另一个 Controller 调用 Controller Ac
这个问题类似于 this ,但我需要访问父成员(不是控制)。我不知道是否可以不使用依赖注入(inject)。 例如,我有一个父级,有一个成员调用用户,我需要从子 Controller 访问用户。 最佳
我有包含 2 个布局的根布局:- 选项面板- 绘制区域 我正在尝试的是访问 OptionsPaneController 中的 DrawAreaController 以调用其绘制方法。下面是 Optio
我的应用程序的 View Controller 层次结构设置如下: UIViewController | UITabBarController | UINavigationCo
我的应用程序的 View Controller 层次结构设置如下: UITabBarController | UINavigationController | | |
当我第一次为我目前在 Storyboard 中开发的应用程序创建基础布局时,我分两步完成: 选择我的 View Controller 并使用 Editor->Embed In->Navigation
设计要求: 显示用户可以选择的项目列表 选择一个项目后,使用后退按钮将用户带到一个新 View 。新 View 应在底部包含第一个屏幕中不存在的选项卡列表 单击选项卡中的项目时,应出现一个带有后退按钮
将父 Controller 设置为“parentCtrl as vm”,并将子 Controller 设置为“childCtrl as vmc”,以避免名称冲突,并且效果良好。 如何在子 Contro
我已经阅读了一些答案,例如关闭当前的 ViewController,但我的情况有所不同,因为我正在展示另一个 ViewController。 虽然我无法访问它的属性,但此代码显示了带有导航 Contr
如我所见,如果我们要实例化一个Model(例如,名为Post),我们只需调用: $post = new Post(); 现在,我还想实例化一个Controller(例如,名为Post,并为此 Cont
我已经疯狂地在整个网络上搜索解决我的问题的方法,但目前还没有。我的问题是我必须检查是否在 HTTP 请求中获得特定文本,该请求在一个 while 循环中,如果我这样做了,那么我应该离开循环并继续线程,
我想用this.get('controllers.pack.query');要得到App.PackQueryController在 App.PackController ,但失败了。 我认为问题是 E
我刚开始使用 Laravel。当我使用 codeigniter 或 zend 框架时,我可以将我的 Controller 组织到一个单独的目录中。例如,我可以创建“user/permission.ph
在 emberjs 前 2 我们可以从另一个 Controller 访问 Controller 或 Controller 中的任何方法 以下方式: App.get('router').get('nav
这可能是非常简单的实现,但我是 iOS 编程的新手,我似乎被卡住了。 所以,基本上,我有一个选项卡式应用程序。我决定除了标签栏之外还需要一个导航栏。为此,我放置了标签栏 Controller ,然后添
我有这个列表 Controller , define([ 'jquery', 'app' ], function ($,app) { app.controller("ListC
我有 3 个 Controller :RootController、FirstController 和 SecondController。我想从 RootController -> FirstCont
我有以下 Controller : /controllers/api/base_controller.rb /controllers/api/v1/articles_controller.rb 当为文
我是 Angular JS 的新手,尝试在另一个 Controller 中调用一个 Controller ,但出现以下错误。 ionic.bundle.js:21157 TypeError: $con
我有一个标签栏 Controller 和它的 3 个 child ,我还有另一个 View ,我制作了一个从 child 到 View Controller 的自定义转场,还有一个从 View Con
我是一名优秀的程序员,十分优秀!