iOS抽屉效果、二级菜单(点击,拖拽滑动)

好像最近,看到好多Android上的抽屉效果,也忍不住想要自己写一个。在Android里面可以用SlidingDrawer,很方便的实现。IOS上面就只有自己写了。其实原理很简单就是 UIView 的移动,和一些手势的操作。


[cpp]  view plain copy
  1. //  
  2. //  DrawerView.h  
  3. //  DrawerDemo  
  4. //  
  5. //  Created by Zhouhaifeng on 12-3-27. 
  6. //  Copyright (c) 2012年 CJLU. All rights reserved. 
  7. //  
  8.   
  9. #import <UIKit/UIKit.h> 
  10.   
  11. typedef enum 
  12. {  
  13.     DrawerViewStateUp = 0,  
  14.     DrawerViewStateDown  
  15. }DrawerViewState;  
  16.   
  17. @interface DrawerView : UIView<UIGestureRecognizerDelegate> 
  18. {  
  19.     UIImageView *arrow;         //向上拖拽时显示的图片      
  20.    
  21.     CGPoint upPoint;            //抽屉拉出时的中心点 
  22.     CGPoint downPoint;          //抽屉收缩时的中心点 
  23.       
  24.     UIView *parentView;         //抽屉所在的view 
  25.     UIView *contentView;        //抽屉里面显示的内容 
  26.       
  27.     DrawerViewState drawState;  //当前抽屉状态 
  28. }  
  29.   
  30. - (id)initWithView:(UIView *) contentview parentView :(UIView *) parentview; 
  31. - (void)handlePan:(UIPanGestureRecognizer *)recognizer; 
  32. - (void)handleTap:(UITapGestureRecognizer *)recognizer; 
  33. - (void)transformArrow:(DrawerViewState) state; 
  34.   
  35. @property (nonatomic,retain) UIView *parentView;  
  36. @property (nonatomic,retain) UIView *contentView;  
  37. @property (nonatomic,retain) UIImageView *arrow;    
  38. @property (nonatomic) DrawerViewState drawState;   
  39.   
  40. @end  
[cpp]  view plain copy
  1. //  
  2. //  DrawerView.h  
  3. //  DrawerDemo  
  4. //  
  5. //  Created by Zhouhaifeng on 12-3-27.  
  6. //  Copyright (c) 2012年 CJLU. All rights reserved.  
  7. //  
  8.   
  9. #import <UIKit/UIKit.h>  
  10.   
  11. typedef enum  
  12. {  
  13.     DrawerViewStateUp = 0,  
  14.     DrawerViewStateDown  
  15. }DrawerViewState;  
  16.   
  17. @interface DrawerView : UIView<UIGestureRecognizerDelegate>  
  18. {  
  19.     UIImageView *arrow;         //向上拖拽时显示的图片      
  20.    
  21.     CGPoint upPoint;            //抽屉拉出时的中心点  
  22.     CGPoint downPoint;          //抽屉收缩时的中心点  
  23.       
  24.     UIView *parentView;         //抽屉所在的view  
  25.     UIView *contentView;        //抽屉里面显示的内容  
  26.       
  27.     DrawerViewState drawState;  //当前抽屉状态  
  28. }  
  29.   
  30. - (id)initWithView:(UIView *) contentview parentView :(UIView *) parentview;  
  31. - (void)handlePan:(UIPanGestureRecognizer *)recognizer;  
  32. - (void)handleTap:(UITapGestureRecognizer *)recognizer;  
  33. - (void)transformArrow:(DrawerViewState) state;  
  34.   
  35. @property (nonatomic,retain) UIView *parentView;  
  36. @property (nonatomic,retain) UIView *contentView;  
  37. @property (nonatomic,retain) UIImageView *arrow;    
  38. @property (nonatomic) DrawerViewState drawState;   
  39.   
  40. @end  

[cpp]  view plain copy
  1. //  
  2. //  DrawerView.m  
  3. //  DrawerDemo  
  4. //  
  5. //  Created by Zhouhaifeng on 12-3-27. 
  6. //  Copyright (c) 2012年 CJLU. All rights reserved. 
  7. //  
  8.   
  9. #import "DrawerView.h" 
  10.   
  11. @implementation DrawerView  
  12. @synthesize contentView,parentView,drawState;  
  13. @synthesize arrow;  
  14.   
  15. - (id)initWithView:(UIView *) contentview parentView :(UIView *) parentview; 
  16. {  
  17.     self = [super initWithFrame:CGRectMake(0,0,contentview.frame.size.width, contentview.frame.size.height+40)]; 
  18.     if (self) {  
  19.         // Initialization code          
  20.         contentView = contentview;  
  21.         parentView = parentview;  
  22.           
  23.         //一定要开启  
  24.         [parentView setUserInteractionEnabled:YES];  
  25.           
  26.         //嵌入内容区域的背景  
  27.         UIImage *drawer_bg = [UIImage imageNamed:@"drawer_content.png"]; 
  28.         UIImageView *view_bg = [[UIImageView alloc]initWithImage:drawer_bg]; 
  29.         [view_bg setFrame:CGRectMake(0,40,contentview.frame.size.width, contentview.bounds.size.height+40)]; 
  30.         [self addSubview:view_bg];  
  31.       
  32.         //头部拉拽的区域背景  
  33.         UIImage *drawer_handle = [UIImage imageNamed:@"drawer_handlepng.png"]; 
  34.         UIImageView *view_handle = [[UIImageView alloc]initWithImage:drawer_handle]; 
  35.         [view_handle setFrame:CGRectMake(0,0,contentview.frame.size.width,40)]; 
  36.         [self addSubview:view_handle];  
  37.           
  38.         //箭头的图片  
  39.         UIImage *drawer_arrow = [UIImage imageNamed:@"drawer_arrow.png"]; 
  40.         arrow = [[UIImageView alloc]initWithImage:drawer_arrow];  
  41.         [arrow setFrame:CGRectMake(0,0,28,28)];  
  42.         arrow.center = CGPointMake(contentview.frame.size.width/2, 20); 
  43.         [self addSubview:arrow];  
  44.           
  45.         //嵌入内容的UIView  
  46.         [contentView setFrame:CGRectMake(0,40,contentview.frame.size.width, contentview.bounds.size.height+40)]; 
  47.         [self addSubview:contentview];  
  48.           
  49.         //移动的手势  
  50.         UIPanGestureRecognizer *panRcognize=[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];   
  51.         panRcognize.delegate=self;    
  52.         [panRcognize setEnabled:YES];    
  53.         [panRcognize delaysTouchesEnded];    
  54.         [panRcognize cancelsTouchesInView];   
  55.           
  56.         [self addGestureRecognizer:panRcognize];  
  57.           
  58.         //单击的手势  
  59.         UITapGestureRecognizer *tapRecognize = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];   
  60.         tapRecognize.numberOfTapsRequired = 1;    
  61.         tapRecognize.delegate = self;    
  62.         [tapRecognize setEnabled :YES];    
  63.         [tapRecognize delaysTouchesBegan];    
  64.         [tapRecognize cancelsTouchesInView];    
  65.           
  66.         [self addGestureRecognizer:tapRecognize];  
  67.           
  68.         //设置两个位置的坐标  
  69.         downPoint = CGPointMake(parentview.frame.size.width/2, parentview.frame.size.height+contentview.frame.size.height/2-40); 
  70.         upPoint = CGPointMake(parentview.frame.size.width/2, parentview.frame.size.height-contentview.frame.size.height/2-40); 
  71.         self.center =  downPoint;  
  72.           
  73.         //设置起始状态  
  74.         drawState = DrawerViewStateDown;  
  75.     }  
  76.     return self;  
  77. }  
  78.   
  79.   
  80. #pragma UIGestureRecognizer Handles    
  81. /*    
  82. *  移动图片处理的函数 
  83. *  @recognizer 移动手势 
  84. */    
  85. - (void)handlePan:(UIPanGestureRecognizer *)recognizer {   
  86.       
  87.      
  88.     CGPoint translation = [recognizer translationInView:parentView];   
  89.     if (self.center.y + translation.y < upPoint.y) { 
  90.         self.center = upPoint;  
  91.     }else if(self.center.y + translation.y > downPoint.y) 
  92.     {  
  93.         self.center = downPoint;  
  94.     }else{  
  95.         self.center = CGPointMake(self.center.x,self.center.y + translation.y);   
  96.     }  
  97.     [recognizer setTranslation:CGPointMake(0, 0) inView:parentView];   
  98.       
  99.     if (recognizer.state == UIGestureRecognizerStateEnded) {   
  100.         [UIView animateWithDuration:0.75 delay:0.15 options:UIViewAnimationOptionCurveEaseOut animations:^{   
  101.                 if (self.center.y < downPoint.y*4/5) { 
  102.                     self.center = upPoint;  
  103.                     [self transformArrow:DrawerViewStateUp]; 
  104.                 }else  
  105.                 {  
  106.                     self.center = downPoint;  
  107.                     [self transformArrow:DrawerViewStateDown]; 
  108.                 }  
  109.   
  110.         } completion:nil];    
  111.    
  112.     }      
  113. }    
  114.   
  115. /* 
  116. *  handleTap 触摸函数 
  117. *  @recognizer  UITapGestureRecognizer 触摸识别器
  118. */    
  119. -(void) handleTap:(UITapGestureRecognizer *)recognizer   
  120. {    
  121.         [UIView animateWithDuration:0.75 delay:0.15 options:UIViewAnimationOptionTransitionCurlUp animations:^{   
  122.             if (drawState == DrawerViewStateDown) { 
  123.                 self.center = upPoint;  
  124.                 [self transformArrow:DrawerViewStateUp];  
  125.             }else  
  126.             {  
  127.                 self.center = downPoint;  
  128.                 [self transformArrow:DrawerViewStateDown];  
  129.             }  
  130.         } completion:nil];    
  131.    
  132. }   
  133.   
  134. /* 
  135. *  transformArrow 改变箭头方向
  136. *  state  DrawerViewState 抽屉当前状态 
  137. */   
  138. -(void)transformArrow:(DrawerViewState) state 
  139. {  
  140.         //NSLog(@"DRAWERSTATE :%d  STATE:%d",drawState,state); 
  141.         [UIView animateWithDuration:0.3 delay:0.35 options:UIViewAnimationOptionCurveEaseOut animations:^{   
  142.            if (state == DrawerViewStateUp){    
  143.                     arrow.transform = CGAffineTransformMakeRotation(M_PI); 
  144.                 }else  
  145.                 {  
  146.                      arrow.transform = CGAffineTransformMakeRotation(0); 
  147.                 }  
  148.         } completion:^(BOOL finish){ 
  149.                drawState = state;  
  150.         }];    
  151.           
  152.      
  153. }  
  154.   
  155. @end  
[cpp]  view plain copy
  1. //  
  2. //  DrawerView.m  
  3. //  DrawerDemo  
  4. //  
  5. //  Created by Zhouhaifeng on 12-3-27.  
  6. //  Copyright (c) 2012年 CJLU. All rights reserved.  
  7. //  
  8.   
  9. #import "DrawerView.h"  
  10.   
  11. @implementation DrawerView  
  12. @synthesize contentView,parentView,drawState;  
  13. @synthesize arrow;  
  14.   
  15. - (id)initWithView:(UIView *) contentview parentView :(UIView *) parentview;  
  16. {  
  17.     self = [super initWithFrame:CGRectMake(0,0,contentview.frame.size.width, contentview.frame.size.height+40)];  
  18.     if (self) {  
  19.         // Initialization code          
  20.         contentView = contentview;  
  21.         parentView = parentview;  
  22.           
  23.         //一定要开启  
  24.         [parentView setUserInteractionEnabled:YES];  
  25.           
  26.         //嵌入内容区域的背景  
  27.         UIImage *drawer_bg = [UIImage imageNamed:@"drawer_content.png"];  
  28.         UIImageView *view_bg = [[UIImageView alloc]initWithImage:drawer_bg];  
  29.         [view_bg setFrame:CGRectMake(0,40,contentview.frame.size.width, contentview.bounds.size.height+40)];  
  30.         [self addSubview:view_bg];  
  31.       
  32.         //头部拉拽的区域背景  
  33.         UIImage *drawer_handle = [UIImage imageNamed:@"drawer_handlepng.png"];  
  34.         UIImageView *view_handle = [[UIImageView alloc]initWithImage:drawer_handle];  
  35.         [view_handle setFrame:CGRectMake(0,0,contentview.frame.size.width,40)];  
  36.         [self addSubview:view_handle];  
  37.           
  38.         //箭头的图片  
  39.         UIImage *drawer_arrow = [UIImage imageNamed:@"drawer_arrow.png"];  
  40.         arrow = [[UIImageView alloc]initWithImage:drawer_arrow];  
  41.         [arrow setFrame:CGRectMake(0,0,28,28)];  
  42.         arrow.center = CGPointMake(contentview.frame.size.width/2, 20);  
  43.         [self addSubview:arrow];  
  44.           
  45.         //嵌入内容的UIView  
  46.         [contentView setFrame:CGRectMake(0,40,contentview.frame.size.width, contentview.bounds.size.height+40)];  
  47.         [self addSubview:contentview];  
  48.           
  49.         //移动的手势  
  50.         UIPanGestureRecognizer *panRcognize=[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];    
  51.         panRcognize.delegate=self;    
  52.         [panRcognize setEnabled:YES];    
  53.         [panRcognize delaysTouchesEnded];    
  54.         [panRcognize cancelsTouchesInView];   
  55.           
  56.         [self addGestureRecognizer:panRcognize];  
  57.           
  58.         //单击的手势  
  59.         UITapGestureRecognizer *tapRecognize = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];    
  60.         tapRecognize.numberOfTapsRequired = 1;    
  61.         tapRecognize.delegate = self;    
  62.         [tapRecognize setEnabled :YES];    
  63.         [tapRecognize delaysTouchesBegan];    
  64.         [tapRecognize cancelsTouchesInView];    
  65.           
  66.         [self addGestureRecognizer:tapRecognize];  
  67.           
  68.         //设置两个位置的坐标  
  69.         downPoint = CGPointMake(parentview.frame.size.width/2, parentview.frame.size.height+contentview.frame.size.height/2-40);  
  70.         upPoint = CGPointMake(parentview.frame.size.width/2, parentview.frame.size.height-contentview.frame.size.height/2-40);  
  71.         self.center =  downPoint;  
  72.           
  73.         //设置起始状态  
  74.         drawState = DrawerViewStateDown;  
  75.     }  
  76.     return self;  
  77. }  
  78.   
  79.   
  80. #pragma UIGestureRecognizer Handles    
  81. /*     
  82.  *  移动图片处理的函数  
  83.  *  @recognizer 移动手势  
  84.  */    
  85. - (void)handlePan:(UIPanGestureRecognizer *)recognizer {    
  86.       
  87.      
  88.     CGPoint translation = [recognizer translationInView:parentView];   
  89.     if (self.center.y + translation.y < upPoint.y) {  
  90.         self.center = upPoint;  
  91.     }else if(self.center.y + translation.y > downPoint.y)  
  92.     {  
  93.         self.center = downPoint;  
  94.     }else{  
  95.         self.center = CGPointMake(self.center.x,self.center.y + translation.y);    
  96.     }  
  97.     [recognizer setTranslation:CGPointMake(0, 0) inView:parentView];    
  98.       
  99.     if (recognizer.state == UIGestureRecognizerStateEnded) {    
  100.         [UIView animateWithDuration:0.75 delay:0.15 options:UIViewAnimationOptionCurveEaseOut animations:^{    
  101.                 if (self.center.y < downPoint.y*4/5) {  
  102.                     self.center = upPoint;  
  103.                     [self transformArrow:DrawerViewStateUp];  
  104.                 }else  
  105.                 {  
  106.                     self.center = downPoint;  
  107.                     [self transformArrow:DrawerViewStateDown];  
  108.                 }  
  109.   
  110.         } completion:nil];    
  111.    
  112.     }      
  113. }    
  114.   
  115. /*  
  116.  *  handleTap 触摸函数  
  117.  *  @recognizer  UITapGestureRecognizer 触摸识别器  
  118.  */    
  119. -(void) handleTap:(UITapGestureRecognizer *)recognizer    
  120. {    
  121.         [UIView animateWithDuration:0.75 delay:0.15 options:UIViewAnimationOptionTransitionCurlUp animations:^{    
  122.             if (drawState == DrawerViewStateDown) {  
  123.                 self.center = upPoint;  
  124.                 [self transformArrow:DrawerViewStateUp];  
  125.             }else  
  126.             {  
  127.                 self.center = downPoint;  
  128.                 [self transformArrow:DrawerViewStateDown];  
  129.             }  
  130.         } completion:nil];    
  131.    
  132. }   
  133.   
  134. /*  
  135.  *  transformArrow 改变箭头方向 
  136.  *  state  DrawerViewState 抽屉当前状态  
  137.  */   
  138. -(void)transformArrow:(DrawerViewState) state  
  139. {  
  140.         //NSLog(@"DRAWERSTATE :%d  STATE:%d",drawState,state);  
  141.         [UIView animateWithDuration:0.3 delay:0.35 options:UIViewAnimationOptionCurveEaseOut animations:^{    
  142.            if (state == DrawerViewStateUp){     
  143.                     arrow.transform = CGAffineTransformMakeRotation(M_PI);  
  144.                 }else  
  145.                 {  
  146.                      arrow.transform = CGAffineTransformMakeRotation(0);  
  147.                 }  
  148.         } completion:^(BOOL finish){  
  149.                drawState = state;  
  150.         }];    
  151.           
  152.      
  153. }  
  154.   
  155. @end 

你可能感兴趣的:(抽屉效果,iOS抽屉效果,iOS二级菜单,iOS抽屉效果二级菜单)