標籤:des style blog http color io os 使用 ar
這篇文章是我的【iOS開發每日小筆記】系列中的一片,記錄的是今天在開發工作中遇到的,可以用很短的文章或很小的demo示範解釋出來的小心得小技巧。它們可能會給使用者體驗、代碼效率得到一些提升,或是之前自己沒有接觸過的技術,很開心的學到了,放在這裡得瑟一下。90%的作用是協助自己回顧、記憶、複習。
原本以為國慶假期可以有時間看看書,寫寫部落格。實際上大部分時間都被趕場參加婚禮和到處去親戚家串門吃飯所佔用。眼看明天還剩最後一天時間,今天趕緊來更新一篇,也算是沒有完全荒廢這7天長假吧!
Facebook的用戶端的登入輸入框,有一種很漂亮的效果,就是當使用者輸入的使用者名稱和口令資訊有誤時,整個輸入介面會左右晃動一下,提示使用者“登入錯誤”,十分有意思。其實,這種效果實現起來也是很簡單的。下面分享兩種思路。
首先來看一下效果,當點擊下方按鈕時,灰色的UIView會左右晃動。
(gif圖片效果不是太好,真機跑出來要更好一些。)
兩種思路均是用CAAnimation實現,只不過一種使用繪製路徑的方法為CAAnimation設定路徑,另一種是利用“主要畫面格”設定value來實現。
1.1,路徑法:
1 // 2 // ViewController.m 3 // ShakeInputViewDemo 4 // 5 // Created by pigpigdaddy on 14-10-6. 6 // Copyright (c) 2014年 pigpigdaddy. All rights reserved. 7 // 8 9 #import "ViewController.h"10 11 @interface ViewController ()12 13 @property (nonatomic, strong)UIView *shakeView;14 @property (nonatomic, strong)UIButton *button;15 16 @end17 18 @implementation ViewController19 20 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil21 {22 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];23 if (self) {24 // Custom initialization25 }26 return self;27 }28 29 - (void)viewDidLoad30 {31 [super viewDidLoad];32 // Do any additional setup after loading the view.33 34 self.button = [UIButton buttonWithType:UIButtonTypeSystem];35 [self.button setTitle:@"左右抖動" forState:UIControlStateNormal];36 self.button.frame = CGRectMake(100, 300, 100, 40);37 [self.button addTarget:self action:@selector(shakeAction) forControlEvents:UIControlEventTouchUpInside];38 [self.view addSubview:self.button];39 40 self.shakeView = [[UIView alloc] initWithFrame:CGRectMake(50, 80, 220, 180)];41 self.shakeView.backgroundColor = [UIColor grayColor];42 [self.view addSubview:self.shakeView];43 }44 45 - (void)didReceiveMemoryWarning46 {47 [super didReceiveMemoryWarning];48 // Dispose of any resources that can be recreated.49 }50 51 /*52 #pragma mark - Navigation53 54 // In a storyboard-based application, you will often want to do a little preparation before navigation55 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender56 {57 // Get the new view controller using [segue destinationViewController].58 // Pass the selected object to the new view controller.59 }60 */61 62 - (void)shakeAction63 {64 // 晃動次數65 static int numberOfShakes = 4;66 // 晃動幅度(相對於總寬度)67 static float vigourOfShake = 0.04f;68 // 晃動延續時常(秒)69 static float durationOfShake = 0.5f;70 71 CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];72 73 // 方法一:繪製路徑74 CGRect frame = self.shakeView.frame;75 // 建立路徑76 CGMutablePathRef shakePath = CGPathCreateMutable();77 // 起始點78 CGPathMoveToPoint(shakePath, NULL, CGRectGetMidX(frame), CGRectGetMidY(frame));79 for (int index = 0; index < numberOfShakes; index++)80 {81 // 添加晃動路徑 幅度由大變小82 CGPathAddLineToPoint(shakePath, NULL, CGRectGetMidX(frame) - frame.size.width * vigourOfShake*(1-(float)index/numberOfShakes),CGRectGetMidY(frame));83 CGPathAddLineToPoint(shakePath, NULL, CGRectGetMidX(frame) + frame.size.width * vigourOfShake*(1-(float)index/numberOfShakes),CGRectGetMidY(frame));84 }85 // 閉合86 CGPathCloseSubpath(shakePath);87 shakeAnimation.path = shakePath;88 shakeAnimation.duration = durationOfShake;89 // 釋放90 CFRelease(shakePath);91 92 [self.shakeView.layer addAnimation:shakeAnimation forKey:kCATransition];93 }
1.2,設定“主要畫面格”,讓CAAnimation自動“補齊”幀與幀之間的動畫,只需改變如下函數:
1 - (void)shakeAction 2 { 3 // 晃動次數 4 static int numberOfShakes = 4; 5 // 晃動幅度(相對於總寬度) 6 static float vigourOfShake = 0.04f; 7 // 晃動延續時常(秒) 8 static float durationOfShake = 0.5f; 9 10 CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];11 12 // 方法二:主要畫面格(點)13 CGPoint layerPosition = self.shakeView.layer.position;14 15 // 起始點16 NSValue *value1=[NSValue valueWithCGPoint:self.shakeView.layer.position];17 // 關鍵點數組18 NSMutableArray *values = [[NSMutableArray alloc] initWithObjects:value1, nil];19 for (int i = 0; i<numberOfShakes; i++) {20 // 左右晃動的點21 NSValue *valueLeft = [NSValue valueWithCGPoint:CGPointMake(layerPosition.x-self.shakeView.frame.size.width*vigourOfShake*(1-(float)i/numberOfShakes), layerPosition.y)];22 NSValue *valueRight = [NSValue valueWithCGPoint:CGPointMake(layerPosition.x+self.shakeView.frame.size.width*vigourOfShake*(1-(float)i/numberOfShakes), layerPosition.y)];23 24 [values addObject:valueLeft];25 [values addObject:valueRight];26 }27 // 最後迴歸到起始點28 [values addObject:value1];29 30 shakeAnimation.values = values;31 shakeAnimation.duration = durationOfShake;32 33 34 [self.shakeView.layer addAnimation:shakeAnimation forKey:kCATransition];35 }
兩種方法的效果是一樣的。
demo:https://github.com/pigpigdaddy/ShakeInputViewDemo
【iOS開發每日小筆記(十二)】仿Facebook登入介面 錯誤提示抖動 利用CAAnimation設定動畫效果