【IOS】实现IOS版的抽屉效果(点击,拖拽滑动)

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


//
//  DrawerView.h
//  DrawerDemo
//
//  Created by Zhouhaifeng on 12-3-27.
//  Copyright (c) 2012年 CJLU. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef enum
{
    DrawerViewStateUp = 0,
    DrawerViewStateDown
}DrawerViewState;

@interface DrawerView : UIView<UIGestureRecognizerDelegate>
{
    UIImageView *arrow;         //向上拖拽时显示的图片    
 
    CGPoint upPoint;            //抽屉拉出时的中心点
    CGPoint downPoint;          //抽屉收缩时的中心点
    
    UIView *parentView;         //抽屉所在的view
    UIView *contentView;        //抽屉里面显示的内容
    
    DrawerViewState drawState;  //当前抽屉状态
}

- (id)initWithView:(UIView *) contentview parentView :(UIView *) parentview;
- (void)handlePan:(UIPanGestureRecognizer *)recognizer;
- (void)handleTap:(UITapGestureRecognizer *)recognizer;
- (void)transformArrow:(DrawerViewState) state;

@property (nonatomic,retain) UIView *parentView;
@property (nonatomic,retain) UIView *contentView;
@property (nonatomic,retain) UIImageView *arrow;  
@property (nonatomic) DrawerViewState drawState; 

@end

//
//  DrawerView.m
//  DrawerDemo
//
//  Created by Zhouhaifeng on 12-3-27.
//  Copyright (c) 2012年 CJLU. All rights reserved.
//

#import "DrawerView.h"

@implementation DrawerView
@synthesize contentView,parentView,drawState;
@synthesize arrow;

- (id)initWithView:(UIView *) contentview parentView :(UIView *) parentview;
{
    self = [super initWithFrame:CGRectMake(0,0,contentview.frame.size.width, contentview.frame.size.height+40)];
    if (self) {
        // Initialization code        
        contentView = contentview;
        parentView = parentview;
        
        //一定要开启
        [parentView setUserInteractionEnabled:YES];
        
        //嵌入内容区域的背景
        UIImage *drawer_bg = [UIImage imageNamed:@"drawer_content.png"];
        UIImageView *view_bg = [[UIImageView alloc]initWithImage:drawer_bg];
        [view_bg setFrame:CGRectMake(0,40,contentview.frame.size.width, contentview.bounds.size.height+40)];
        [self addSubview:view_bg];
    
        //头部拉拽的区域背景
        UIImage *drawer_handle = [UIImage imageNamed:@"drawer_handlepng.png"];
        UIImageView *view_handle = [[UIImageView alloc]initWithImage:drawer_handle];
        [view_handle setFrame:CGRectMake(0,0,contentview.frame.size.width,40)];
        [self addSubview:view_handle];
        
        //箭头的图片
        UIImage *drawer_arrow = [UIImage imageNamed:@"drawer_arrow.png"];
        arrow = [[UIImageView alloc]initWithImage:drawer_arrow];
        [arrow setFrame:CGRectMake(0,0,28,28)];
        arrow.center = CGPointMake(contentview.frame.size.width/2, 20);
        [self addSubview:arrow];
        
        //嵌入内容的UIView
        [contentView setFrame:CGRectMake(0,40,contentview.frame.size.width, contentview.bounds.size.height+40)];
        [self addSubview:contentview];
        
        //移动的手势
        UIPanGestureRecognizer *panRcognize=[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];  
        panRcognize.delegate=self;  
        [panRcognize setEnabled:YES];  
        [panRcognize delaysTouchesEnded];  
        [panRcognize cancelsTouchesInView]; 
        
        [self addGestureRecognizer:panRcognize];
        
        //单击的手势
        UITapGestureRecognizer *tapRecognize = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];  
        tapRecognize.numberOfTapsRequired = 1;  
        tapRecognize.delegate = self;  
        [tapRecognize setEnabled :YES];  
        [tapRecognize delaysTouchesBegan];  
        [tapRecognize cancelsTouchesInView];  
        
        [self addGestureRecognizer:tapRecognize];
        
        //设置两个位置的坐标
        downPoint = CGPointMake(parentview.frame.size.width/2, parentview.frame.size.height+contentview.frame.size.height/2-40);
        upPoint = CGPointMake(parentview.frame.size.width/2, parentview.frame.size.height-contentview.frame.size.height/2-40);
        self.center =  downPoint;
        
        //设置起始状态
        drawState = DrawerViewStateDown;
    }
    return self;
}


#pragma UIGestureRecognizer Handles  
/*    
 *  移动图片处理的函数 
 *  @recognizer 移动手势 
 */  
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {  
    
   
    CGPoint translation = [recognizer translationInView:parentView]; 
    if (self.center.y + translation.y < upPoint.y) {
        self.center = upPoint;
    }else if(self.center.y + translation.y > downPoint.y)
    {
        self.center = downPoint;
    }else{
        self.center = CGPointMake(self.center.x,self.center.y + translation.y);  
    }
    [recognizer setTranslation:CGPointMake(0, 0) inView:parentView];  
    
    if (recognizer.state == UIGestureRecognizerStateEnded) {  
        [UIView animateWithDuration:0.75 delay:0.15 options:UIViewAnimationOptionCurveEaseOut animations:^{  
                if (self.center.y < downPoint.y*4/5) {
                    self.center = upPoint;
                    [self transformArrow:DrawerViewStateUp];
                }else
                {
                    self.center = downPoint;
                    [self transformArrow:DrawerViewStateDown];
                }

        } completion:nil];  
 
    }    
}  

/* 
 *  handleTap 触摸函数 
 *  @recognizer  UITapGestureRecognizer 触摸识别器 
 */  
-(void) handleTap:(UITapGestureRecognizer *)recognizer  
{  
        [UIView animateWithDuration:0.75 delay:0.15 options:UIViewAnimationOptionTransitionCurlUp animations:^{  
            if (drawState == DrawerViewStateDown) {
                self.center = upPoint;
                [self transformArrow:DrawerViewStateUp];
            }else
            {
                self.center = downPoint;
                [self transformArrow:DrawerViewStateDown];
            }
        } completion:nil];  
 
} 

/* 
 *  transformArrow 改变箭头方向
 *  state  DrawerViewState 抽屉当前状态 
 */ 
-(void)transformArrow:(DrawerViewState) state
{
        //NSLog(@"DRAWERSTATE :%d  STATE:%d",drawState,state);
        [UIView animateWithDuration:0.3 delay:0.35 options:UIViewAnimationOptionCurveEaseOut animations:^{  
           if (state == DrawerViewStateUp){   
                    arrow.transform = CGAffineTransformMakeRotation(M_PI);
                }else
                {
                     arrow.transform = CGAffineTransformMakeRotation(0);
                }
        } completion:^(BOOL finish){
               drawState = state;
        }];  
        
   
}

@end

这样就是实现了,图片是从360里面抠出来,处理的不是很好,大家见谅。

Demo的下载地址:http://download.csdn.net/detail/toss156/4177553

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值