iOS开发-Pop动画教程

本文资料来自http://www.appcoda.com/facebook-pop-framework-intro/ 如有错误欢迎各位指出

如果你使用 CocoaPods,你可以添加下面这句话到你的工程中的Podfile文件中;

pod ‘pop’

如果你没有CocoaPods,你能下载Pop这个框架在https://github.com/facebook/pop 之后添加pop这个文件夹到你的工程中,并且确保你的工程中的“Other Linker Flags”选项已经添加了“-lc++”;

5BAD58AF-BE99-4A65-954D-90C7CD300FB9.png

使用Pop

首先导入头文件

#import "POP.h"

例子一:UITableViewCell Animation

pop-animation-1-1.gif

我们创建一个动画在tableViewCell上,首先添加一个放大的动画当我们点击cell的时候,当我们手离开屏幕的时候,我们用将cell上缩回原先的大小用spring animation;

重写cell中的setHighlighted方法,代码如下:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    [super setHighlighted:highlighted animated:animated];
    if (self.highlighted) {
        POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewScaleXY];
        scaleAnimation.duration = 0.1;
        scaleAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1, 1)];
        [self.textLabel pop_addAnimation:scaleAnimation forKey:@"scalingUp"];
        
        
        
    } else {
        POPSpringAnimation *sprintAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewScaleXY];
        sprintAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(0.9, 0.9)];
        sprintAnimation.velocity = [NSValue valueWithCGPoint:CGPointMake(2, 2)];
        sprintAnimation.springBounciness = 20.f;
        [self.textLabel pop_addAnimation:sprintAnimation forKey:@"springAnimation"];
    }
}

Pop为我们提供许多创建动画的预定义属性,你能找到这些属性在“POPAnimatableProperty.h”文件中;

例子二:Animating a Like Button

pop-animation-2.gif

创建一个controller在storyBoard中,在controller中创建一个UITextField,之后添加一个send和like按钮,like按钮在send按钮的上面,默认的情况下我们展示like按钮,当用户输入文字在textField中我们隐藏like按钮,展示send按钮用一个动画;
创建一个名为FacebookButtonAnimationViewController的类 继承UIViewController;在这个类中添加like和send按钮,还有textField的变量;

@interface FacebookButtonAnimationViewController ()
@property (weak, nonatomic) IBOutlet UITextField *msgTextField;
@property (weak, nonatomic) IBOutlet UIButton *likeButton;
@property (weak, nonatomic) IBOutlet UIButton *sendButton;

@end

实现UITextField的代理方法:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

在这个方法中我们可以监控用户输入和删除文字,内部的实现如下:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *comment;
    if(range.length == 0)
    {
        comment = [NSString stringWithFormat:@"%@%@", textField.text, string];
    }
    else
    {
        comment = [textField.text substringToIndex:textField.text.length - range.length];
    }
    
    if (comment.length == 0) {
        //Show like
        [self showLikeButton];
    }
    else
    {
        //Show Send
        [self showSendButton];
    }
    return YES;
}

之后我们实现showLikeButton和showSendButton

-(void)showLikeButton
{
    self.likeButton.hidden = NO;
    self.sendButton.hidden = YES;
    
    POPSpringAnimation *spin = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerRotation];
   
    spin.fromValue = @(M_PI / 4);
    spin.toValue = @(0);
    spin.springBounciness = 20;
    spin.velocity = @(10);
    [self.likeButton.layer pop_addAnimation:spin forKey:@"likeAnimation"];
}

-(void)showSendButton
{
    if (self.sendButton.isHidden) {
        
        self.likeButton.hidden = YES;
        self.sendButton.hidden = NO;
        POPSpringAnimation *sprintAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewScaleXY];
        
        sprintAnimation.velocity = [NSValue valueWithCGPoint:CGPointMake(8, 8)];
        sprintAnimation.springBounciness = 20.f;
        [self.sendButton pop_addAnimation:sprintAnimation forKey:@"sendAnimation"];
    }
}

例子三:Wrong Password Animation

pop-animation-3-2.gif

首先在storyBoard中新建一个controller,在controller中添加textField和一个button;
接下来创建一个继承UIViewControll名位WrongPasswordViewController的类,在类中创建一个UITextField的变量与storyBoard中的textField关联,命名为passwordTextField;

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

@end

之后我们创建一个名位login的方法为Login Button,在这个方法中我们校验密码是否正确,如果不正确我们为textField添加一个摇晃动画;

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

例子四:Custom View Controller Transition

pop-animation-4.gif

这个例子将教你们怎么跳转到一个控制器用自定义动画,我们在控制器中建一个按钮“present”,当用户点击这个按钮,app跳转到另一个控制器中用一个自定义动画,从iOS7开始,你能够自定义控制器的过渡动画用UIViewController的transitioningDelegate.在这个代理中,我们要实现UIViewControllerTransitioningDelegate的代理方法,还有提供过渡动画的实现;

首先,创建在storyBoard中创建俩个controller和俩个新类,命名为 “CustomVCTransitionViewController”和 “CustomModalViewController”
UI设计如下:

custom-view-controller-ui-hd.jpg

现在我们实现CustomVCTransitionViewController中Present按钮的点击,首先是添加UIViewControllerTransitioningDelegate的声明;
在CustomVCTransitionViewController.m 我们引入一下头文件:

#import "CustomModalViewController.h"

#import "PresentingAnimationController.h"
#import "DismissingAnimationController.h"

接下来实现Present按钮的action和代理方法:

- (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];
}

当Present按钮被点击的时候,didClickOnPresent会响应点击事件,在这个方法中我们初始化CustomModalViewController,并且设置过度代理方法对于当前这个controller;
我们必须实现 UIViewControllerTransitioningDelegate中俩个必须实现的代理方法,animationControllerForPresentedController方法返回跳转到CustomModalViewController的过渡动画.相反,animationControllerForDismissedController返回动画为了要dismiss的控制器;
现在我们创建一个继承NSObject的新类叫做PresentingAnimationController,在这个类中我们遵守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"];

    
}

第一个方法返回过渡时间,为了实现动画,我们实现animateTransition方法,这里我们将实现怎么去跳转。

现在我们创建一个继承NSObject的新类叫做DismissingAnimationController,在这个类中我们遵守UIViewControllerAnimatedTransitioning协议.
相似,我们在DismissingAnimationController.m添加如下方法:

- (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"];
 
}

来到CustomModalViewController.m中,更新viewDidLoad方法并且实现didClickOnClose方法:

-(void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.layer.cornerRadius = 8.f;
}

- (IBAction)didClickOnClose:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

其它参考资料 :http://adad184.com/2015/03/11/intro-to-pop/

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

推荐阅读更多精彩内容