iOS侧滑菜单实现

今天做项目的时候,产品经理说要实现类似facebook那样侧滑菜单的效果,其实现在很多app都实现了类似的效果,比如网易新闻,搜狗输入板等。于是就在网上搜索其实现的原理,虽然也搜到了不少,但是发现它们实现的都过于复杂,代码看起来实在是费劲,我是一个非常注重简单明了的人,极力主张一切从简,能简单就一定不复杂,于是就自己尝试来实现了。

 

首先简单说一下我实现的原理:需要两个UIView,一个是放在中间的CenterView,另一个是滑动时左边显示出来的LeftView。先把LeftView添加到ViewController中,然后再添加CenterView,这样CenterView就把LeftView给盖住了,一开始看到的自然就是CenterView了。因为滑动是在CenterView上进行的,因此需要对CenterView添加手势识别,滑动时改变CenterView中心点的坐标,这样被覆盖住的LeftView就显示出来了。这个就是实现的基本原理,下面我进行详细的分析。

 

我们先看LeftView,为了和CenterView区分,我把它的背景设为红色,然后中间放了一个按钮:

 

LeftView.h


01. //
02. //  LeftView.h
03. //  SlideView
04. //
05. //  Created by hejinlai on 13-8-13.
06. //  Copyright (c) 2013年 yunzhisheng. All rights reserved.
07. //
08. #import <UIKit/UIKit.h>
09. @interface LeftView : UIView
10. @end

LeftView.m

 

01. //
02. //  LeftView.m
03. //  SlideView
04. //
05. //  Created by hejinlai on 13-8-13.
06. //  Copyright (c) 2013年 yunzhisheng. All rights reserved.
07. //
08. #import "LeftView.h"
09. @implementation LeftView
10. - (id)initWithFrame:(CGRect)frame
11. {
12. self = [super initWithFrame:frame];
13. if (self) {
14. // Initialization code www.it165.net
15.  
16. self.backgroundColor = [UIColor redColor];
17.  
18.  
19. UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
20. btn.frame = CGRectMake(0, 0, 100, 50);
21. [btn setTitle:@"LeftView" forState:UIControlStateNormal];
22. btn.center = CGPointMake(140, 264);
23. [btn addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside];
24. [self addSubview:btn];
25.  
26. }
27. return self;
28. }
29. - (void)onClick:(UIButton *)button
30. {
31. NSLog(@"LeftView button pressed!");
32. }
33. @end

再来看CenterView,首先声明了屏幕的中心点坐标和一个手势识别:

 

1. #import <UIKit/UIKit.h>
2. @interface CenterView : UIView
3. {
4. UIPanGestureRecognizer *panGestureRecognizer;
5. float centerX;
6. float centerY;
7. }
8. @end

在CenterView初始化的时候,计算屏幕中心点坐标,设置背景为绿色,添加左上角按钮和手势识别

 

01. - (id)initWithFrame:(CGRect)frame
02. {
03. self = [super initWithFrame:frame];
04. if (self) {
05.  
06. CGRect screen = [[UIScreen mainScreen] bounds];
07. centerX = screen.size.width / 2;
08. centerY = screen.size.height / 2;
09.  
10. self.backgroundColor = [UIColor greenColor];
11.  
12. // 左上角按钮
13. UIButton *leftUpBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
14. leftUpBtn.frame = CGRectMake(10, 10, 40, 40);
15. [leftUpBtn addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
16. [self addSubview:leftUpBtn];
17.  
18. panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
19. [self addGestureRecognizer:panGestureRecognizer];
20. }
21. return self;
22. }

CenterView最终位置实际上有两个:第一个位置是充满整个屏幕,此时它的中心点就是屏幕的中心,把LeftView整个遮住;第二个位置是中心点在右边,而左边只露出一小部分在屏幕中,这样底部的LeftView就可以显示出来。

我把CenterView最右边的中心点横坐标的位置设为420,相当于CenterView左边露出了60大小在屏幕中。还有一个问题是,滑动停止时,CenterView回到第一个位置还是第二个位置?这里我设置了一个边界值280,如果中心点横坐标小于280就回到第一个位置,大于280就回到第二个位置,下面是这两个常量的定义:


1. #define MAX_CENTER_X 420
2. #define BOUND_X 280

当然这两个值可以根据自己的需要进行调整。

CenterView左上角按钮点击时,需要在两个位置之间进行切换,即如果此时是第一个位置要回到第二个位置,第二个位置要回到第一个位置:


01. - (void)buttonPressed:(UIButton *)button
02. {
03. [UIView animateWithDuration:0.2 animations:^(void){
04.  
05. if (self.center.x == centerX) {
06. self.center = CGPointMake(MAX_CENTER_X, centerY);
07. }else if (self.center.x == MAX_CENTER_X){
08. self.center = CGPointMake(centerX, centerY);
09. }
10.  
11. }];
12.  
13. }

为了看起来比较平滑,加入了动画效果。

接下来我们看下滑动时处理的逻辑。首先是计算出滑动后的中心点横坐标:


1. CGPoint translation = [recognizer translationInView:self];
2. float x = self.center.x + translation.x;

由于CenterView是不能移到左边的,即CenterView中心点横坐标最小值为centerX,当中心点坐标小于这个值时,需要重置:

 

1. if (x < centerX) {
2. x = centerX;
3. }
4. self.center = CGPointMake(x, centerY);

当滑动结束的时候,需要判断此时中心点左边落到那个区域,如果小于边界值,则回到第一个位置,大于边界值则回到第二个位置,为了看起来比较平滑,加入了动画效果:

 

01. if (recognizer.state == UIGestureRecognizerStateEnded) {
02.  
03. [UIView animateWithDuration:0.2 animations:^(void){
04.  
05. if (x > BOUND_X) {
06. self.center = CGPointMake(MAX_CENTER_X, centerY);
07. }else{
08. self.center = CGPointMake(centerX, centerY);
09. }
10.  
11. }];
12.  
13.  
14. }
15.  
16. [recognizer setTranslation:CGPointZero inView:self];

最后在ViewController加入这两个UIVIew,注意先添加LeftView,然后再添加CenterView:

 

01. - (void)viewDidLoad
02. {
03. [super viewDidLoad];
04. // Do any additional setup after loading the view, typically from a nib.
05.  
06. CGRect screen = [[UIScreen mainScreen] bounds];
07. CGFloat width = screen.size.width;
08. CGFloat height = screen.size.height;
09.  
10. leftView = [[LeftView alloc] init];
11. leftView.frame = CGRectMake(0, 0, width, height);
12. [self.view addSubview:leftView];
13.  
14. centerView = [[CenterView alloc] init];
15. centerView.frame = CGRectMake(0, 0, width, height);
16. [self.view addSubview:centerView];
17. }

运行结果:

 


工程源码: http://www.it165.net/uploadfile/2013/0814/20130814094341743.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值