今天作項目的時候,產品經理說要實現相似facebook那樣側滑菜單的效果,其實如今不少app都實現了相似的效果,好比網易新聞,搜狗輸入板等。因而就在網上搜索其實現的原理,雖然也搜到了很多,可是發現它們實現的都過於複雜,代碼看起來實在是費勁,我是一個很是注重簡單明瞭的人,極力主張一切從簡,能簡單就必定不復雜,因而就本身嘗試來實現了。app
首先簡單說一下我實現的原理:須要兩個UIView,一個是放在中間的CenterView,另外一個是滑動時左邊顯示出來的LeftView。先把LeftView添加到ViewController中,而後再添加CenterView,這樣CenterView就把LeftView給蓋住了,一開始看到的天然就是CenterView了。由於滑動是在CenterView上進行的,所以須要對CenterView添加手勢識別,滑動時改變CenterView中心點的座標,這樣被覆蓋住的LeftView就顯示出來了。這個就是實現的基本原理,下面我進行詳細的分析。ide
咱們先看LeftView,爲了和CenterView區分,我把它的背景設爲紅色,而後中間放了一個按鈕:測試
LeftView.h動畫
// // LeftView.h // SlideView // // Created by hejinlai on 13-8-13. // Copyright (c) 2013年 yunzhisheng. All rights reserved. // #import <UIKit/UIKit.h> @interface LeftView : UIView @end
LeftView.mcode
// // LeftView.m // SlideView // // Created by hejinlai on 13-8-13. // Copyright (c) 2013年 yunzhisheng. All rights reserved. // #import "LeftView.h" @implementation LeftView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = [UIColor redColor]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame = CGRectMake(0, 0, 100, 50); [btn setTitle:@"LeftView" forState:UIControlStateNormal]; btn.center = CGPointMake(140, 264); [btn addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:btn]; } return self; } - (void)onClick:(UIButton *)button { NSLog(@"LeftView button pressed!"); } @end
再來看CenterView,首先聲明瞭屏幕的中心點座標和一個手勢識別:orm
#import <UIKit/UIKit.h> @interface CenterView : UIView { UIPanGestureRecognizer *panGestureRecognizer; float centerX; float centerY; } @end
在CenterView初始化的時候,計算屏幕中心點座標,設置背景爲綠色,添加左上角按鈕和手勢識別blog
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { CGRect screen = [[UIScreen mainScreen] bounds]; centerX = screen.size.width / 2; centerY = screen.size.height / 2; self.backgroundColor = [UIColor greenColor]; // 左上角按鈕 UIButton *leftUpBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; leftUpBtn.frame = CGRectMake(10, 10, 40, 40); [leftUpBtn addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:leftUpBtn]; panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; [self addGestureRecognizer:panGestureRecognizer]; } return self; }
CenterView最終位置實際上有兩個:第一個位置是充滿整個屏幕,此時它的中心點就是屏幕的中心,把LeftView整個遮住;第二個位置是中心點在右邊,而左邊只露出一小部分在屏幕中,這樣底部的LeftView就能夠顯示出來。get
我把CenterView最右邊的中心點橫座標的位置設爲420,至關於CenterView左邊露出了60大小在屏幕中。還有一個問題是,滑動中止時,CenterView回到第一個位置仍是第二個位置?這裏我設置了一個邊界值280,若是中心點橫座標小於280就回到第一個位置,大於280就回到第二個位置,下面是這兩個常量的定義:animation
#define MAX_CENTER_X 420 #define BOUND_X 280
固然這兩個值能夠根據本身的須要進行調整。產品
CenterView左上角按鈕點擊時,須要在兩個位置之間進行切換,即若是此時是第一個位置要回到第二個位置,第二個位置要回到第一個位置:
- (void)buttonPressed:(UIButton *)button { [UIView animateWithDuration:0.2 animations:^(void){ if (self.center.x == centerX) { self.center = CGPointMake(MAX_CENTER_X, centerY); }else if (self.center.x == MAX_CENTER_X){ self.center = CGPointMake(centerX, centerY); } }]; }
爲了看起來比較平滑,加入了動畫效果。
接下來咱們看下滑動時處理的邏輯。首先是計算出滑動後的中心點橫座標:
CGPoint translation = [recognizer translationInView:self]; float x = self.center.x + translation.x;
因爲CenterView是不能移到左邊的,即CenterView中心點橫座標最小值爲centerX,當中心點座標小於這個值時,須要重置:
if (x < centerX) { x = centerX; } self.center = CGPointMake(x, centerY);
當滑動結束的時候,須要判斷此時中心點左邊落到那個區域,若是小於邊界值,則回到第一個位置,大於邊界值則回到第二個位置,爲了看起來比較平滑,加入了動畫效果:
if (recognizer.state == UIGestureRecognizerStateEnded) { [UIView animateWithDuration:0.2 animations:^(void){ if (x > BOUND_X) { self.center = CGPointMake(MAX_CENTER_X, centerY); }else{ self.center = CGPointMake(centerX, centerY); } }]; } [recognizer setTranslation:CGPointZero inView:self];
最後在ViewController加入這兩個UIVIew,注意先添加LeftView,而後再添加CenterView:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CGRect screen = [[UIScreen mainScreen] bounds]; CGFloat width = screen.size.width; CGFloat height = screen.size.height; leftView = [[LeftView alloc] init]; leftView.frame = CGRectMake(0, 0, width, height); [self.view addSubview:leftView]; centerView = [[CenterView alloc] init]; centerView.frame = CGRectMake(0, 0, width, height); [self.view addSubview:centerView]; }
運行結果:
爲了讓你們測試方便,附件中我上傳了源代碼,歡迎你們下載!