iOS抽屉效果
2016-01-26 14:09
232 查看
SlideViewController.h
#define kScreenSize [[UIScreen mainScreen] bounds].size #define kScreenWidth [[UIScreen mainScreen] bounds].size.width #define kScreenHeight [[UIScreen mainScreen] bounds].size.height #define kMainPageDistance 100 //打开左侧窗时,中视图(右视图)露出的宽度 #define kMainPageScale 1.0 //打开左侧窗时,中视图(右视图)缩放比例 #define kMainPageCenter CGPointMake(kScreenWidth + kScreenWidth * kMainPageScale / 2.0 - kMainPageDistance, kScreenHeight / 2) //打开左侧窗时,中视图中心点 #define vCouldChangeDeckStateDistance (kScreenWidth - kMainPageDistance) / 2.0 - 40 //滑动距离大于此数时,状态改变(关--》开,或者开--》关) #define vSpeedFloat 0.7 //滑动速度 #define kLeftAlpha 0.9 //左侧蒙版的最大值 #define kLeftCenterX 30 //左侧初始偏移量 #define kLeftScale 0.7 //左侧初始缩放比例 #define vDeckCanNotPanViewTag 987654 // 不响应此侧滑的View的tag #import <UIKit/UIKit.h> #import "UIView_extra.h" @interface LeftSlideViewController : UIViewController //滑动速度系数-建议在0.5-1之间。默认为0.5 @property (nonatomic,assign) CGFloat speedf; //左侧窗控制器 @property (nonatomic,strong) UIViewController *leftVC; @property (nonatomic,strong) UIViewController *mainVC; //点击手势控制器,是否允许点击视图恢复视图位置。默认为yes @property (nonatomic,strong) UITapGestureRecognizer *sideslipTapGes; //滑动手势控制器 @property (nonatomic,strong) UIPanGestureRecognizer *pan; //侧滑窗是否关闭(关闭时显示为主页) @property (nonatomic,assign) BOOL closed; /** @brief 初始化侧滑控制器 @param leftVC 右视图控制器 mainVC 中间视图控制器 @result instancetype 初始化生成的对象 */ - (instancetype)initWithLeftView:(UIViewController *)leftVC andMainView:(UIViewController *)mainVC; /** @brief 关闭左视图 */ - (void)closeLeftView; /** @brief 打开左视图 */ - (void)openLeftView; /** * 设置滑动开关是否开启 * * @param enabled YES:支持滑动手势,NO:不支持滑动手势 */ - (void)setPanEnabled: (BOOL) enabled;SlideViewController.m
#import "LeftSlideViewController.h" @interface LeftSlideViewController ()<UIGestureRecognizerDelegate> { CGFloat _scalef; //实时横向位移 } @property (nonatomic,strong) UITableView *leftTableview; @property (nonatomic,assign) CGFloat leftTableviewW; @property (nonatomic,strong) UIView *contentView; @end @implementation LeftSlideViewController - (void)viewDidLoad { [super viewDidLoad]; } /** @brief 初始化侧滑控制器 @param leftVC 左视图控制器 mainVC 中间视图控制器 @result instancetype 初始化生成的对象 */ - (instancetype)initWithLeftView:(UIViewController *)leftVC andMainView:(UIViewController *)mainVC{ if(self = [super init]){ self.speedf = vSpeedFloat; self.leftVC = leftVC; self.mainVC = mainVC; [self addChildViewController:self.leftVC]; [self addChildViewController:self.mainVC]; //滑动手势 self.pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)]; [self.mainVC.view addGestureRecognizer:self.pan]; [self.pan setCancelsTouchesInView:YES]; self.pan.delegate = self; self.leftVC.view.hidden = YES; [self.view addSubview:self.leftVC.view]; //蒙版 UIView *view = [[UIView alloc] init]; view.frame = self.leftVC.view.bounds; view.backgroundColor = [UIColor blackColor]; view.alpha = 0.5; self.contentView = view; [self.leftVC.view addSubview:view]; //获取左侧tableview for (UIView *obj in self.leftVC.view.subviews) { if ([obj isKindOfClass:[UITableView class]]) { self.leftTableview = (UITableView *)obj; } } self.leftTableview.backgroundColor = [UIColor clearColor]; self.leftTableview.frame = CGRectMake(0, 0, kScreenWidth - kMainPageDistance, kScreenHeight); //设置左侧tableview的初始位置和缩放系数 self.leftTableview.transform = CGAffineTransformMakeScale(kLeftScale, kLeftScale); self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); [self.view addSubview:self.mainVC.view]; self.closed = YES;//初始时侧滑窗关闭 } return self; } - (void) viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; self.leftVC.view.hidden = NO; } #pragma mark - 滑动手势 - (void) handlePan: (UIPanGestureRecognizer *)rec{ CGPoint point = [rec translationInView:self.view]; _scalef = (point.x * self.speedf + _scalef); BOOL needMoveWithTap = YES; //是否还需要跟随手指移动 if (((self.mainVC.view.x <= 0) && (_scalef <= 0)) || ((self.mainVC.view.x >= (kScreenWidth - kMainPageDistance )) && (_scalef >= 0))){ //边界值管控 _scalef = 0; needMoveWithTap = NO; } //根据视图位置判断是左滑还是右边滑动 if (needMoveWithTap && (rec.view.frame.origin.x >= 0) && (rec.view.frame.origin.x <= (kScreenWidth - kMainPageDistance))){ CGFloat recCenterX = rec.view.center.x + point.x * self.speedf; if (recCenterX < kScreenWidth * 0.5 - 2) { recCenterX = kScreenWidth * 0.5; } CGFloat recCenterY = rec.view.center.y; rec.view.center = CGPointMake(recCenterX,recCenterY); //scale 1.0~kMainPageScale CGFloat scale = 1 - (1 - kMainPageScale) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); rec.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,scale, scale); [rec setTranslation:CGPointMake(0, 0) inView:self.view]; CGFloat leftTabCenterX = kLeftCenterX + ((kScreenWidth - kMainPageDistance) * 0.5 - kLeftCenterX) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); //leftScale kLeftScale~1.0 CGFloat leftScale = kLeftScale + (1 - kLeftScale) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); self.leftTableview.center = CGPointMake(leftTabCenterX, kScreenHeight * 0.5); self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity, leftScale,leftScale); //tempAlpha kLeftAlpha~0 CGFloat tempAlpha = kLeftAlpha - kLeftAlpha * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); self.contentView.alpha = tempAlpha; }else{ //超出范围, if (self.mainVC.view.x < 0){ [self closeLeftView]; _scalef = 0; }else if (self.mainVC.view.x > (kScreenWidth - kMainPageDistance)){ [self openLeftView]; _scalef = 0; } } //手势结束后修正位置,超过约一半时向多出的一半偏移 if (rec.state == UIGestureRecognizerStateEnded) { if (fabs(_scalef) > vCouldChangeDeckStateDistance){ if (self.closed){ [self openLeftView]; }else{ [self closeLeftView]; } }else{ if (self.closed){ [self closeLeftView]; }else{ [self openLeftView]; } } _scalef = 0; } } #pragma mark - 单击手势 -(void)handeTap:(UITapGestureRecognizer *)tap{ if ((!self.closed) && (tap.state == UIGestureRecognizerStateEnded)){ [UIView beginAnimations:nil context:nil]; tap.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); tap.view.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2,[UIScreen mainScreen].bounds.size.height/2); self.closed = YES; self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,kLeftScale,kLeftScale); self.contentView.alpha = kLeftAlpha; [UIView commitAnimations]; _scalef = 0; [self removeSingleTap]; } } #pragma mark - 修改视图位置 /** @brief 关闭左视图 */ - (void)closeLeftView{ [UIView beginAnimations:nil context:nil]; self.mainVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); self.mainVC.view.center = CGPointMake(kScreenWidth / 2, kScreenHeight / 2); self.closed = YES; self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,kLeftScale,kLeftScale); self.contentView.alpha = kLeftAlpha; [UIView commitAnimations]; [self removeSingleTap]; } /** @brief 打开左视图 */ - (void)openLeftView;{ [UIView beginAnimations:nil context:nil]; self.mainVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,kMainPageScale,kMainPageScale); self.mainVC.view.center = kMainPageCenter; self.closed = NO; self.leftTableview.center = CGPointMake((kScreenWidth - kMainPageDistance) * 0.5, kScreenHeight * 0.5); self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); self.contentView.alpha = 0; [UIView commitAnimations]; [self disableTapButton]; } #pragma mark - 行为收敛控制 - (void)disableTapButton{ for (UIButton *tempButton in [_mainVC.view subviews]){ [tempButton setUserInteractionEnabled:NO]; } //单击 if (!self.sideslipTapGes){ //单击手势 self.sideslipTapGes= [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handeTap:)]; [self.sideslipTapGes setNumberOfTapsRequired:1]; [self.mainVC.view addGestureRecognizer:self.sideslipTapGes]; self.sideslipTapGes.cancelsTouchesInView = YES; //点击事件盖住其它响应事件,但盖不住Button; } } //关闭行为收敛 - (void) removeSingleTap{ for (UIButton *tempButton in [self.mainVC.view subviews]){ [tempButton setUserInteractionEnabled:YES]; } [self.mainVC.view removeGestureRecognizer:self.sideslipTapGes]; self.sideslipTapGes = nil; } /** * 设置滑动开关是否开启 * * @param enabled YES:支持滑动手势,NO:不支持滑动手势 */ - (void)setPanEnabled: (BOOL) enabled{ [self.pan setEnabled:enabled]; } -(BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch { if(touch.view.tag == vDeckCanNotPanViewTag){ return NO; } else{ return YES; } } @end
相关文章推荐
- iOS开发 小工具
- srxboys自述
- iOS-让结构体类型frame的属性可以直接修改
- ios扫一扫功能实现
- iOS开发系列手势、音频
- iOS-ERROR ITMS-90046: "Invalid Code Signing Entitlements.
- OC-CoreGraphics - CGGeometry.h详解
- iOS细节 开发
- iOS监听键盘的删除按键事件
- iOS 关于Presenting view controllers on detached view controllers is discouraged的警告
- [IOS 开发] 无限后台运行
- iOS中的三大事件
- iOS开发流程总结
- ios定位当前城市
- iOS Provisioning Profile(Certificate)与Code Signing详解
- iOS学习之VFL语言简介
- iOS开发时间戳与时间,时区的转换,汉字与UTF8,16进制的转换
- xcode7.2不能真机调试ios9.2.1系统设备的解决方法
- iOS取出手机里的所有图片 ---简单的方法
- iOS字符串解析---》字典