iOS简单抽屉效果的实现方法

Endora ·
更新时间:2024-11-10
· 107 次阅读

本文实例为大家分享了iOS实现简单抽屉效果的具体代码,供大家参考,具体内容如下

实现思路及步骤:

1、首先准备要滑动的view

#warning 第一步 - (void)addChildView {     // left     UIView *leftView = [[UIView alloc] initWithFrame:self.view.bounds];     leftView.backgroundColor = [UIColor greenColor];     [self.view addSubview:leftView];     _leftView = leftView;     // right     UIView *rightView = [[UIView alloc] initWithFrame:self.view.bounds];     rightView.backgroundColor = [UIColor blueColor];     [self.view addSubview:rightView];     _rightView = rightView;     // mainView     UIView *mainView = [[UIView alloc] initWithFrame:self.view.bounds];     mainView.backgroundColor = [UIColor redColor];     [self.view addSubview:mainView];     _mainView = mainView; }

2、监听触摸事件,记录横轴方向的偏移量,有了偏移量就可以通过偏移量改动视图的位置

#warning 第二布 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {     // 获取UITouch对象     UITouch *touch = [touches anyObject];     // 获取当前点     CGPoint currentPoint = [touch locationInView:self.view];     // 获取上一个点     CGPoint prePoint = [touch previousLocationInView:self.view];     // x轴偏移量:当手指移动一点的时候,x偏移多少     CGFloat offsetX = currentPoint.x - prePoint.x;     // 设置当前主视图的frame     _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];     _isDraging = YES; }   如何实时监听一个对象的属性(只能监听对象,不能监听结构体)?kvo   // 1.监听  2 ,实现:observeValueForKeyPath 方法   /**      *  给_mainView添加一个观察者      *      *  KeyPath:监听frame这个属性      *      *  options:监听新值的改变      */     [_mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; //实时监听mainview的frame // 当_mainView的frame属性改变的时候就会调用 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {     NSLog(@"%@", NSStringFromCGRect(_mainView.frame));//当前的frame     if (_mainView.frame.origin.x < 0) { // 主界面的x<0,往左移动         // 显示右边         _rightView.hidden = NO;         // 隐藏左边         _leftView.hidden = YES;     }else if (_mainView.frame.origin.x > 0){ // 往右移动         // 显示左边         _rightView.hidden = YES;         // 隐藏右边         _leftView.hidden = NO;     } } 

当x轴偏移的时候,如何缩放高度?
当x偏移时,y轴缩小为: x的偏移量/

#define HMMaxY 60 // 当手指偏移一点,根据X轴的偏移量算出当前主视图的frame - (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX {     CGFloat screenW = [UIScreen mainScreen].bounds.size.width;     CGFloat screenH = [UIScreen mainScreen].bounds.size.height;     // 获取y轴偏移量,手指每移动一点,y轴偏移多少     CGFloat offsetY = offsetX * HMMaxY / screenW;//HMMaxY 缩放的最大Y      CGFloat scale = (screenH - 2 * offsetY) / screenH;//比例      if (_mainView.frame.origin.x < 0) { // 往左边滑动         scale = (screenH + 2 * offsetY) / screenH;     }     // 获取之前的frame     CGRect frame = _mainView.frame;     frame.origin.x += offsetX;     frame.size.height = frame.size.height *scale;     frame.size.width = frame.size.width *scale;     frame.origin.y = (screenH - frame.size.height) * 0.5;     return frame; }

定位:

#define HMRTarget 250 #define HMLTarget -220 /*  _mainView.frame.origin.x > screenW * 0.5 定位到右边   CGRectGetMaxX(_mainView.frame) < screenW * 0.5 定位到左边 -220  */ // 定位 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {     // 复位     if (_isDraging == NO && _mainView.frame.origin.x != 0) {         [UIView animateWithDuration:0.25 animations:^{             _mainView.frame = self.view.bounds;         }];     }     CGFloat screenW = [UIScreen mainScreen].bounds.size.width;     CGFloat target = 0;     if (_mainView.frame.origin.x > screenW * 0.5) { // 定位到右边         target = HMRTarget;     }else if (CGRectGetMaxX(_mainView.frame) < screenW * 0.5) { // 定位到左边         target = HMLTarget;     }     [UIView animateWithDuration:0.25 animations:^{         if (target) { // 在需要定位左边或者右边             // 获取x轴偏移量             CGFloat offsetX = target - _mainView.frame.origin.x;             // 设置当前主视图的frame             _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];         }else{ // 还原             _mainView.frame = self.view.bounds;         }     }];     _isDraging = NO; }

全:

@interface HMDrawViewController () @property (nonatomic, assign) BOOL isDraging; @end @implementation HMDrawViewController - (void)viewDidLoad {     // UIViewController     [super viewDidLoad];     // Do any additional setup after loading the view.     // 1.添加子控件     [self addChildView]; #warning 第三步 观察_mainView的frame改变     // 2.监听     /**      *  给_mainView添加一个观察者      *      *  KeyPath:监听frame这个属性      *      *  options:监听新值的改变      */     [_mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; } // 当_mainView的frame属性改变的时候就会调用 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {     NSLog(@"%@", NSStringFromCGRect(_mainView.frame));     if (_mainView.frame.origin.x < 0) { // 往左移动         // 显示右边         _rightView.hidden = NO;         // 隐藏左边         _leftView.hidden = YES;     }else if (_mainView.frame.origin.x > 0){ // 往右移动         // 显示左边         _rightView.hidden = YES;         // 隐藏右边         _leftView.hidden = NO;     } } #warning 第一步 - (void)addChildView {     // left     UIView *leftView = [[UIView alloc] initWithFrame:self.view.bounds];     leftView.backgroundColor = [UIColor greenColor];     [self.view addSubview:leftView];     _leftView = leftView;     // right     UIView *rightView = [[UIView alloc] initWithFrame:self.view.bounds];     rightView.backgroundColor = [UIColor blueColor];     [self.view addSubview:rightView];     _rightView = rightView;     // mainView     UIView *mainView = [[UIView alloc] initWithFrame:self.view.bounds];     mainView.backgroundColor = [UIColor redColor];     [self.view addSubview:mainView];     _mainView = mainView; } #warning 第二布 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {     // 获取UITouch对象     UITouch *touch = [touches anyObject];     // 获取当前点     CGPoint currentPoint = [touch locationInView:self.view];     // 获取上一个点     CGPoint prePoint = [touch previousLocationInView:self.view];     // x轴偏移量:当手指移动一点的时候,x偏移多少     CGFloat offsetX = currentPoint.x - prePoint.x;     // 设置当前主视图的frame     _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];     _isDraging = YES; } #warning 第四步 #define HMMaxY 60 // 当手指偏移一点,根据X轴的偏移量算出当前主视图的frame - (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX {     CGFloat screenW = [UIScreen mainScreen].bounds.size.width;     CGFloat screenH = [UIScreen mainScreen].bounds.size.height;     // 获取y轴偏移量,手指每移动一点,y轴偏移多少     CGFloat offsetY = offsetX * HMMaxY / screenW;     CGFloat scale = (screenH - 2 * offsetY) / screenH;     if (_mainView.frame.origin.x < 0) { // 往左边滑动         scale = (screenH + 2 * offsetY) / screenH;     }     // 获取之前的frame     CGRect frame = _mainView.frame;     frame.origin.x += offsetX;     frame.size.height = frame.size.height *scale;     frame.size.width = frame.size.width *scale;     frame.origin.y = (screenH - frame.size.height) * 0.5;     return frame; } #define HMRTarget 250 #define HMLTarget -220 /*  _mainView.frame.origin.x > screenW * 0.5 定位到右边   CGRectGetMaxX(_mainView.frame) < screenW * 0.5 定位到左边 -220  */ // 定位 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {     // 复位     if (_isDraging == NO && _mainView.frame.origin.x != 0) {         [UIView animateWithDuration:0.25 animations:^{             _mainView.frame = self.view.bounds;         }];     }     CGFloat screenW = [UIScreen mainScreen].bounds.size.width;     CGFloat target = 0;     if (_mainView.frame.origin.x > screenW * 0.5) { // 定位到右边         target = HMRTarget;     }else if (CGRectGetMaxX(_mainView.frame) < screenW * 0.5) { // 定位到左边         target = HMLTarget;     }     [UIView animateWithDuration:0.25 animations:^{         if (target) { // 在需要定位左边或者右边             // 获取x轴偏移量             CGFloat offsetX = target - _mainView.frame.origin.x;             // 设置当前主视图的frame             _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];         }else{ // 还原             _mainView.frame = self.view.bounds;         }     }];     _isDraging = NO; }



方法 抽屉 IOS

需要 登录 后方可回复, 如果你还没有账号请 注册新账号