Pop(Part2)

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

  • Example #3:錯(cuò)誤密碼動(dòng)畫
    作為Mac用戶,你肯定熟悉OS X系統(tǒng)里的密碼框.當(dāng)你密碼輸入錯(cuò)誤時(shí),輸入框會(huì)晃動(dòng).現(xiàn)在我們將用Pop實(shí)現(xiàn)這種動(dòng)畫效果.
    第一步,添加一個(gè)新的view controller.在上面增加一個(gè)text field和一個(gè)登錄按鈕.然后在Example List View Controller和新頁面之間添加segue.設(shè)置此segue的identifier為"openWrongPass".完成后你的interface頁面會(huì)如下圖一般:

pop-wrong-password-ui-hd.jpg

接下來創(chuàng)建一個(gè)名為WrongPasswordViewController的類文件并將它設(shè)置為新建的View Controller的類.創(chuàng)建text field的變量并命名為passwordTextField.

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

然后創(chuàng)建一個(gè)名為login的登錄按鈕.
如前文所述,我們將在text field上增加一個(gè)晃動(dòng)動(dòng)畫來標(biāo)示錯(cuò)誤密碼.示例中并不驗(yàn)證密碼而僅僅是在點(diǎn)擊登錄按鈕時(shí)展示晃動(dòng)動(dòng)畫.
實(shí)現(xiàn)登錄方法如下:

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

上面的代碼相當(dāng)簡潔.我們創(chuàng)建了一個(gè)屬性為kPOPLayerPositionX屬性的POPSpringAnimation.這個(gè)屬性表示text field以X軸為方向.
最后記得在WrongPasswordViewController.m開頭導(dǎo)入POP.h:

#import <pop/POP.h>

Cool!完成了!運(yùn)行程序來測(cè)試下.

pop-animation-3-2.gif
  • Example #4:自定義ViewController轉(zhuǎn)場(chǎng)
    最后一個(gè)例子,我將展示view controller的轉(zhuǎn)場(chǎng)動(dòng)畫.我們?cè)谝粋€(gè)view controller上面添加一個(gè)"Present"按鈕.當(dāng)用戶點(diǎn)擊時(shí),應(yīng)用將通過一個(gè)自定義動(dòng)畫來呈現(xiàn)另一個(gè)view Controller.iOS7以后,我們能夠利用UIViewController中的transitioningDelegate來自定義轉(zhuǎn)場(chǎng)動(dòng)畫.這個(gè)代理方法,需要繼承于UIViewControllerAnimatedTransitioning.提供了view controllers之間的轉(zhuǎn)場(chǎng)動(dòng)畫.
    首先在storyboard上創(chuàng)建兩個(gè)view Controller和兩個(gè)類.命名為"CustomVCTransitionViewController"和"CustomModalViewController".將他們對(duì)應(yīng)于相應(yīng)的view Controllers.Model view controller(紅色的)的storyboard ID 設(shè)置為"customModal".將Example List View Controller和CustomVCTransitionViewController通過segue連接.并將此segue的identifier設(shè)置為"openCustomTransition".
    UI如下圖所示:

custom-view-controller-ui-hd.jpg

你可以快速測(cè)試下app.當(dāng)你點(diǎn)擊Custom VC Transition時(shí)CustomVCTransitionController將會(huì)出現(xiàn).
現(xiàn)在我們將編寫CustomVCTransitionViewController來處理Present按鈕.在CustomVCTransitionViewController.h里面添加如下代碼來使其遵從UIViewControllerTransitioningDelegate協(xié)議:

@interface CustomVCTransitionViewController : UIViewController <UIViewControllerTransitioningDelegate>

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

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

添加如下代碼來實(shí)現(xiàn)Present按鈕動(dòng)作和實(shí)現(xiàn)協(xié)議的方法:

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

當(dāng)按鈕點(diǎn)擊時(shí),會(huì)調(diào)用didClickOnPresent方法.這里我們舉例modal view controller,設(shè)置transitioning代理為當(dāng)前view controller.還要設(shè)置modal presentation style為custom.(記得在storyboard連接Present button和這個(gè)方法)
類已經(jīng)遵從了UIViewControllerTransitioningDelegate協(xié)議,因此實(shí)現(xiàn)了其兩個(gè)必須的方法.animationControllerForPresentedController:方法返回的是用于展現(xiàn)modal view controller的轉(zhuǎn)場(chǎng)動(dòng)畫.相反的,animationControllerForDismissedController方法提供的是頁面消失的動(dòng)畫.
我們還沒有創(chuàng)建這兩個(gè)動(dòng)畫類.現(xiàn)在我們新建一個(gè)名為PresentingAnimationController的遵從UIViewControllerAniamtionTransitioning協(xié)議的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"];
}

第一個(gè)方法定義了轉(zhuǎn)場(chǎng)時(shí)間(例如0.5秒).對(duì)于轉(zhuǎn)場(chǎng)動(dòng)畫,我們實(shí)現(xiàn)了animateTransition:方法.在里面我定義了轉(zhuǎn)場(chǎng)動(dòng)畫如何展現(xiàn).首先在轉(zhuǎn)場(chǎng)里通過viewControllerForKey:方法取到"fromView".繼而取得"toView".一旦你取得這兩個(gè)views,就能在之間添加各種動(dòng)畫.這里我們實(shí)現(xiàn)兩種動(dòng)畫:position動(dòng)畫和scale動(dòng)畫.位置動(dòng)畫將使view從屏幕頂部下落到中央.放大縮小動(dòng)畫將view先方法然后回到正常大小.
下面,創(chuàng)建一個(gè)名為DismissingAnimationController遵從UIViewControllerAnimatedTransitioning協(xié)議的類:

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

相似的,通過實(shí)現(xiàn)UIViewControllerAnimatedTransitioning協(xié)議的必須方法來實(shí)現(xiàn)消失動(dòng)畫:

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

當(dāng)modal view 消失時(shí),我們實(shí)現(xiàn)了兩個(gè)動(dòng)畫:關(guān)閉動(dòng)畫和縮小動(dòng)畫.通過這兩個(gè)動(dòng)畫的結(jié)合我們實(shí)現(xiàn)了modal view的消失和移出屏幕.
在CustomModalViewController.m里的viewDidLoad方法里實(shí)現(xiàn)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!該測(cè)試app了.運(yùn)行并測(cè)試下view的轉(zhuǎn)場(chǎng).

pop-animation-4.gif
  • 小結(jié)
    在這篇教程里,我介紹了Facebook的Pop framework.正如你所看到的,這個(gè)動(dòng)畫引擎相當(dāng)好用.如果你理解了這篇教程里的動(dòng)畫技術(shù),將它們用到你的應(yīng)用中吧.
    你可以在the project on Github下載整個(gè)項(xiàng)目.

Girl學(xué)iOS100天 第11天

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容