本文翻譯自: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頁面會如下圖一般:
接下來創建一個名為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!完成了!運行程序來測試下.
- 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如下圖所示:
你可以快速測試下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的轉場.
- 小結
在這篇教程里,我介紹了Facebook的Pop framework.正如你所看到的,這個動畫引擎相當好用.如果你理解了這篇教程里的動畫技術,將它們用到你的應用中吧.
你可以在the project on Github下載整個項目.
Girl學iOS100天 第11天