更好的抽屉效果(ios)

昨天项目基本没啥事了,晚上早早的就回家了,躺在床上无聊地玩着手机(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

呵呵,可以看看效果,是不是感觉好点。。

原文地址:https://www.cnblogs.com/ctaodream/p/3365352.html