Pop(Part2)

本文翻译自:Creating Simple Animations with Facebook’s Pop Framework
Part1在这里

  • Example #3:错误密码动画
    作为Mac用户,你肯定熟悉OS X系统里的密码框.当你密码输入错误时,输入框会晃动.现在我们将用Pop实现这种动画效果.
    第一步,添加一个新的view controller.在上面增加一个text field和一个登录按钮.然后在Example List View Controller和新页面之间添加segue.设置此segue的identifier为"openWrongPass".完成后你的interface页面会如下图一般:

pop-wrong-password-ui-hd.jpg

接下来创建一个名为WrongPasswordViewController的类文件并将它设置为新建的View Controller的类.创建text field的变量并命名为passwordTextField.

@interface WrongPasswordViewController ()
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@end

然后创建一个名为login的登录按钮.
如前文所述,我们将在text field上增加一个晃动动画来标示错误密码.示例中并不验证密码而仅仅是在点击登录按钮时展示晃动动画.
实现登录方法如下:

- (IBAction)login:(id)sender {
    POPSpringAnimation *shake = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionX];
    shake.springBounciness = 20;
    shake.velocity = @(3000);
    [self.passwordTextField.layer pop_addAnimation:shake forKey:@"shakePassword"];
}

上面的代码相当简洁.我们创建了一个属性为kPOPLayerPositionX属性的POPSpringAnimation.这个属性表示text field以X轴为方向.
最后记得在WrongPasswordViewController.m开头导入POP.h:

#import <pop/POP.h>

Cool!完成了!运行程序来测试下.

pop-animation-3-2.gif
  • Example #4:自定义ViewController转场
    最后一个例子,我将展示view controller的转场动画.我们在一个view controller上面添加一个"Present"按钮.当用户点击时,应用将通过一个自定义动画来呈现另一个view Controller.iOS7以后,我们能够利用UIViewController中的transitioningDelegate来自定义转场动画.这个代理方法,需要继承于UIViewControllerAnimatedTransitioning.提供了view controllers之间的转场动画.
    首先在storyboard上创建两个view Controller和两个类.命名为"CustomVCTransitionViewController"和"CustomModalViewController".将他们对应于相应的view Controllers.Model view controller(红色的)的storyboard ID 设置为"customModal".将Example List View Controller和CustomVCTransitionViewController通过segue连接.并将此segue的identifier设置为"openCustomTransition".
    UI如下图所示:

custom-view-controller-ui-hd.jpg

你可以快速测试下app.当你点击Custom VC Transition时CustomVCTransitionController将会出现.
现在我们将编写CustomVCTransitionViewController来处理Present按钮.在CustomVCTransitionViewController.h里面添加如下代码来使其遵从UIViewControllerTransitioningDelegate协议:

@interface CustomVCTransitionViewController : UIViewController <UIViewControllerTransitioningDelegate>

在CustomVCTransitionViewController.m里面增加下面头文件:

#import "CustomModalViewController.h"
#import "PresentingAnimationController.h"
#import "DismissingAnimationController.h"
#import <pop/POP.h>

添加如下代码来实现Present按钮动作和实现协议的方法:

- (IBAction)didClickOnPresent:(id)sender {
        CustomModalViewController *modalVC = [self.storyboard instantiateViewControllerWithIdentifier:@"customModal"];
        modalVC.transitioningDelegate = self;
        modalVC.modalPresentationStyle = UIModalPresentationCustom;
        [self.navigationController presentViewController:modalVC animated:YES completion:nil];
}
 #pragma mark - UIViewControllerTransitionDelegate -
 - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    return [[PresentingAnimationController alloc] init];
}
 - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    return [[DismissingAnimationController alloc] init];
}

当按钮点击时,会调用didClickOnPresent方法.这里我们举例modal view controller,设置transitioning代理为当前view controller.还要设置modal presentation style为custom.(记得在storyboard连接Present button和这个方法)
类已经遵从了UIViewControllerTransitioningDelegate协议,因此实现了其两个必须的方法.animationControllerForPresentedController:方法返回的是用于展现modal view controller的转场动画.相反的,animationControllerForDismissedController方法提供的是页面消失的动画.
我们还没有创建这两个动画类.现在我们新建一个名为PresentingAnimationController的遵从UIViewControllerAniamtionTransitioning协议的NSObject的子类:

#import <UIKit/UIKit.h>
#import "POP.h"
@interface PresentingAnimationController : NSObject <UIViewControllerAnimatedTransitioning>

在PresentingAnimationController.m里添加下面方法:

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
    return 0.5f;
}
 
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
    fromView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
    fromView.userInteractionEnabled = NO;
    
    UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
    toView.frame = CGRectMake(0,
                              0,
                              CGRectGetWidth(transitionContext.containerView.bounds) - 100.f,
                              CGRectGetHeight(transitionContext.containerView.bounds) - 280.f);
    CGPoint p = CGPointMake(transitionContext.containerView.center.x, -transitionContext.containerView.center.y);
    toView.center = p;
    [transitionContext.containerView addSubview:toView];
    
    POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
    positionAnimation.toValue = @(transitionContext.containerView.center.y);
    positionAnimation.springBounciness = 10;
    [positionAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
    POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    scaleAnimation.springBounciness = 20;
    scaleAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1.2, 1.4)];
    [toView.layer pop_addAnimation:positionAnimation forKey:@"positionAnimation"];
    [toView.layer pop_addAnimation:scaleAnimation forKey:@"scaleAnimation"];
}

第一个方法定义了转场时间(例如0.5秒).对于转场动画,我们实现了animateTransition:方法.在里面我定义了转场动画如何展现.首先在转场里通过viewControllerForKey:方法取到"fromView".继而取得"toView".一旦你取得这两个views,就能在之间添加各种动画.这里我们实现两种动画:position动画和scale动画.位置动画将使view从屏幕顶部下落到中央.放大缩小动画将view先方法然后回到正常大小.
下面,创建一个名为DismissingAnimationController遵从UIViewControllerAnimatedTransitioning协议的类:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <pop/POP.h>
 @interface DismissingAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
 @end

相似的,通过实现UIViewControllerAnimatedTransitioning协议的必须方法来实现消失动画:

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
    return 0.5f;
}
 
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
    toView.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
    toView.userInteractionEnabled = YES;
    
    UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
    
    
    POPBasicAnimation *closeAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];
    closeAnimation.toValue = @(-fromView.layer.position.y);
    [closeAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
    
    POPSpringAnimation *scaleDownAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    scaleDownAnimation.springBounciness = 20;
    scaleDownAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    
    [fromView.layer pop_addAnimation:closeAnimation forKey:@"closeAnimation"];
    [fromView.layer pop_addAnimation:scaleDownAnimation forKey:@"scaleDown"];
    
}

当modal view 消失时,我们实现了两个动画:关闭动画和缩小动画.通过这两个动画的结合我们实现了modal view的消失和移出屏幕.
在CustomModalViewController.m里的viewDidLoad方法里实现didClickOnClose方法:

- (void)viewDidLoad {
    [super viewDidLoad];
        // Round corner
    self.view.layer.cornerRadius = 8.f; 
}
 - (IBAction)didClickOnClose:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

最后连接Close按钮和didClickOnClose方法.
Cool!该测试app了.运行并测试下view的转场.

pop-animation-4.gif
  • 小结
    在这篇教程里,我介绍了Facebook的Pop framework.正如你所看到的,这个动画引擎相当好用.如果你理解了这篇教程里的动画技术,将它们用到你的应用中吧.
    你可以在the project on Github下载整个项目.

Girl学iOS100天 第11天

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容