昨天項目基本沒啥事了,晚上早早的就回家了,躺在牀上無聊地玩着手機(Android的),在清理系統垃圾時被一個「360手機助手」給吸引了,ide
其實我是被它的那個抽屜效果給吸引了,此時你也許會以爲我out了 ,一個抽屜效果有啥好吸引人的。動畫
之前在項目中我也用到過抽屜,也看過大量的抽屜效果,大部分時間時只有一個view能夠滑動的,下面那個view是不動的,就像是拉出或推出一個view的效果差很少,ui
但看到這個 360手機助手的抽屜效果時,我以爲原來的那些真沒這個好看。在這個程序中,當你左右拖動那個view A時,另一個view B也會相應的滑動,但滑動的幅度沒有你拖動的那個view A大,不知道我表達清楚沒有,你能夠下載個360手機助手看看。spa
因而今天就模仿了一下,拖動view A時 兩個view均可以滑動,則說明動畫時做用兩個view的。code
下面直接上代碼吧,代碼很簡單,也沒具體完善邏輯,只是個簡單的效果實現 ,瞭解抽屜效果的很容易就看懂的blog
1.工程結構圖get
2.主要的代碼animation
// // Drawer.h // SlideDrawer // // Created by PSH_Chen_Tao on 10/12/13. // Copyright (c) 2013 wolfman. All rights reserved. // #import <UIKit/UIKit.h> //代表當前狀態的枚舉常量 typedef enum{ DrawerStatusLeft, DrawerStatusRight }DrawerStatus; @interface Drawer : UIView //初始化方法 -(id)initWithParent:(UIViewController *)parentViewController firstContent:(UIViewController *)firstContentViewController secondContent:(UIViewController *)secondContentViewController; @end
1 // 2 // Drawer.m 3 // SlideDrawer 4 // 5 // Created by PSH_Chen_Tao on 10/12/13. 6 // Copyright (c) 2013 wolfman. All rights reserved. 7 // 8 9 #import "Drawer.h" 10 #define kDistance 50 11 //#define firstContentMoveDistance 100 12 @implementation Drawer{ 13 UIViewController *parent; 14 15 //控制第一個內容view的controller 16 UIViewController *firstContent; 17 //控制第二個內容view的controller 18 UIViewController *secondContent; 19 20 21 // 左滑時 firstContent的 view的center 22 CGPoint firstLeft; 23 // 右滑時 firstContent的 view的center 24 CGPoint firstRight; 25 26 // 左滑時 secondContent的 view的center 27 CGPoint secondLeft; 28 // 右滑時 secondContent的 view的center 29 CGPoint secondRight; 30 31 // 目前的狀態 32 DrawerStatus status; 33 34 // firstContent 的 center 35 CGPoint firstContentCenter; 36 37 38 //移動比列,這個是關鍵,本程序是相似360手機助手同樣的效果,兩邊的view都是 39 //可同時移動的,在此就須要一個很好的匹配,移動時兩個view的間距不能增大或減少 40 float moveScale; 41 } 42 43 44 -(id)initWithParent:(UIViewController *)parentViewController firstContent:(UIViewController *)firstContentViewController secondContent:(UIViewController *)secondContentViewController{ 45 parent = parentViewController; 46 firstContent = firstContentViewController; 47 secondContent = secondContentViewController; 48 // 爲了便於效果查看 49 firstContent.view.backgroundColor = [UIColor redColor]; 50 secondContent.view.backgroundColor = [UIColor greenColor]; 51 52 //設置frame 53 self = [super initWithFrame:CGRectMake(0, 0, parent.view.frame.size.width, parent.view.frame.size.height)]; 54 if (self) { 55 firstContent.view.frame = CGRectMake(0, 0, self.frame.size.width, parent.view.frame.size.height); 56 [self addSubview:firstContent.view]; 57 secondContent.view.frame = CGRectMake(0, 0, parent.view.frame.size.width, parent.view.frame.size.height); 58 [self addSubview:secondContent.view]; 59 60 // 下面算firstContent 和 secondContent的左右中心點時是要遵循必定關係的, 61 //firstContent 和 secondContent 的可移動距離之和必須等於 parent的寬度 62 firstLeft = CGPointMake(self.frame.size.width/2 - kDistance, self.frame.size.height/2); 63 firstRight = self.center; 64 65 secondLeft = self.center; 66 secondRight = CGPointMake(self.frame.size.width+secondContent.view.frame.size.width/2-kDistance, self.frame.size.height/2); 67 68 firstContent.view.center = firstRight; 69 secondContent.view.center = secondRight; 70 status = DrawerStatusRight; 71 72 // 加入手勢 73 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)]; 74 tap.numberOfTapsRequired = 1; 75 tap.enabled = YES; 76 [secondContent.view addGestureRecognizer:tap]; 77 78 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)]; 79 pan.enabled = YES; 80 [secondContent.view addGestureRecognizer:pan]; 81 82 //設置第一個view 的起始center 83 firstContentCenter = firstContent.view.center; 84 85 //這個是關鍵,爲何要這樣算,爲了防止兩個content view之間的間距發生改變, 86 //因此firstContent 和 secondContent 的可移動距離之和必須等於 parent的寬度 87 moveScale = (float)kDistance/(float)(self.frame.size.width - kDistance); 88 } 89 90 return self; 91 } 92 93 94 -(void)handleTap:(UITapGestureRecognizer *)tap{ 95 // 當secondController徹底出如今屏幕中時,則只有點擊左上角時纔有用 96 // 呵呵,沒啥好寫的,就是簡單地控制下點擊範圍 97 if (status == DrawerStatusLeft) { 98 99 CGPoint p = [tap locationInView:secondContent.view]; 100 if (p.x > kDistance || p.y > 50) { 101 return; 102 } 103 } 104 105 [UIView animateWithDuration:0.3 delay:0.01 options:UIViewAnimationOptionCurveLinear animations:^{ 106 if (status == DrawerStatusRight) { 107 secondContent.view.center = secondLeft; 108 109 firstContent.view.center = firstLeft; 110 status = DrawerStatusLeft; 111 }else{ 112 secondContent.view.center = secondRight; 113 firstContent.view.center = firstRight; 114 status = DrawerStatusRight; 115 } 116 } completion:nil]; 117 118 } 119 120 121 -(void)handlePan:(UIPanGestureRecognizer *)pan{ 122 123 CGPoint point = [pan translationInView:self]; 124 125 if (secondContent.view.center.x + point.x < secondLeft.x) { 126 127 secondContent.view.center = secondLeft; 128 firstContent.view.center = firstLeft; 129 130 }else if (secondContent.view.center.x + point.x > secondRight.x){ 131 132 secondContent.view.center = secondRight; 133 134 firstContent.view.center = firstRight; 135 136 }else{ 137 secondContent.view.center = CGPointMake(secondContent.view.center.x + point.x, secondContent.view.center.y); 138 //firstContent的移動距離必須按照比例計算 139 firstContent.view.center = CGPointMake(firstContent.view.center.x + point.x*moveScale, firstContent.view.center.y); 140 } 141 142 [pan setTranslation:CGPointMake(0, 0) inView:self]; 143 if (pan.state == UIGestureRecognizerStateEnded) { 144 [UIView animateWithDuration:0.3 delay:0.01 options:UIViewAnimationOptionCurveLinear animations:^{ 145 if (secondContent.view.center.x < secondRight.x*4/5) { 146 147 secondContent.view.center = secondLeft; 148 149 firstContent.view.center = firstLeft; 150 status = DrawerStatusLeft; 151 }else{ 152 153 secondContent.view.center = secondRight; 154 firstContent.view.center = firstRight; 155 156 status = DrawerStatusRight; 157 } 158 } completion:nil]; 159 } 160 } 161 162 @end
上面兩段是主要的代碼了,下面是使用的地方it
1 // 2 // ViewController.m 3 // SlideDrawer 4 // 5 // Created by PSH_Chen_Tao on 10/12/13. 6 // Copyright (c) 2013 wolfman. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 #import "FirstViewController.h" 12 #import "SecondViewController.h" 13 #import "Drawer.h" 14 @interface ViewController () 15 16 @end 17 18 @implementation ViewController 19 20 - (void)viewDidLoad 21 { 22 [super viewDidLoad]; 23 // Do any additional setup after loading the view, typically from a nib. 24 25 FirstViewController *fisrt = [[FirstViewController alloc]initWithNibName:@"FirstViewController" bundle:nil]; 26 27 SecondViewController *second = [[SecondViewController alloc]initWithNibName:@"SecondViewController" bundle:nil]; 28 29 Drawer *drawer = [[Drawer alloc]initWithParent:self firstContent:fisrt secondContent:second]; 30 [self.view addSubview:drawer]; 31 } 32 33 - (void)didReceiveMemoryWarning 34 { 35 [super didReceiveMemoryWarning]; 36 // Dispose of any resources that can be recreated. 37 } 38 39 @end
呵呵,能夠看看效果,是否是感受好點。。io