昨天项目基本没啥事了,晚上早早的就回家了,躺在床上无聊地玩着手机(Android的),在清理系统垃圾时被一个“360手机助手”给吸引了,
其实我是被它的那个抽屉效果给吸引了,此时你也许会觉得我out了 ,一个抽屉效果有啥好吸引人的。
以前在项目中我也用到过抽屉,也看过大量的抽屉效果,大部分时间时只有一个view可以滑动的,下面那个view是不动的,就像是拉出或推出一个view的效果差不多,
但看到这个 360手机助手的抽屉效果时,我觉得原来的那些真没这个好看。在这个程序中,当你左右拖动那个view A时,另外一个view B也会相应的滑动,但滑动的幅度没有你拖动的那个view A大,不知道我表达清楚没有,你可以下载个360手机助手看看。
于是今天就模仿了一下,拖动view A时 两个view都可以滑动,则说明动画时作用两个view的。
下面直接上代码吧,代码很简单,也没具体完善逻辑,只是个简单的效果实现 ,了解抽屉效果的很容易就看懂的
1.工程结构图
2.主要的代码
//
// 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
View Code
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
View Code
上面两段是主要的代码了,下面是使用的地方
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
View Code
呵呵,可以看看效果,是不是感觉好点。。