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

 更新时间:2022年08月08日 11:08:37   作者:绿叶清风  
这篇文章主要为大家详细介绍了iOS简单抽屉效果的实现方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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的客户端菜单功能仿百度糯米/美团二级菜单

    iOS的客户端菜单功能仿百度糯米/美团二级菜单

    我刚好最近在开发一个商城项目,实现了一个简单的控件,控件的效果就是类似百度糯米或者美团的二级菜单,非常不错具有参考借鉴价值,对百度糯米 美团二级菜单功能感兴趣的朋友一起看看吧
    2016-11-11
  • IOS关于大型网站抢购、距活动结束,剩余时间倒计时的实现代码

    IOS关于大型网站抢购、距活动结束,剩余时间倒计时的实现代码

    这篇文章主要介绍了IOS关于大型网站抢购、距活动结束,剩余时间倒计时的实现代码的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • 详解IOS开发中生成推送的pem文件

    详解IOS开发中生成推送的pem文件

    这篇文章主要介绍了详解IOS开发中生成推送的pem文件的相关资料,这里提供详细的实现步骤帮助大家实现,希望大家能理解掌握,需要的朋友可以参考下
    2017-08-08
  • 利用iOS实现系统相册大图浏览功能详解

    利用iOS实现系统相册大图浏览功能详解

    查看大图是们日常开发中经常会遇到的一个需求,下面这篇文章主要给大家介绍了关于利用iOS实现系统相册大图浏览功能的相关资料,文中给出了详细的示例代码供大家参考学习,需要的朋友们下面来一起看看吧。
    2017-09-09
  • 理解Objective-C的变量以及面相对象的继承特性

    理解Objective-C的变量以及面相对象的继承特性

    这篇文章主要介绍了理解Objective-C的变量以及面相对象的继承特性,文中的所说的点语法即是'对象名.成员变量名'这种对变量的访问,需要的朋友可以参考下
    2016-01-01
  • iOS-GCD使用详解及实例解析

    iOS-GCD使用详解及实例解析

    这篇文章主要介绍了iOS-GCD使用详解及实例解析的相关资料,需要的朋友可以参考下
    2016-11-11
  • iOS开源一个简单的订餐app UI框架

    iOS开源一个简单的订餐app UI框架

    这篇文章主要介绍了iOS开源一个简单的订餐app UI框架,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • iOS 9无法访问HTTP的解决方法

    iOS 9无法访问HTTP的解决方法

    这篇文章主要为大家详细介绍了iOS 9无法访问HTTP的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • iOS开发底层探索界面优化示例详解

    iOS开发底层探索界面优化示例详解

    这篇文章主要为大家介绍了iOS开发底层探索界面优化示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • iOS二维码的生成代码

    iOS二维码的生成代码

    这篇文章主要为大家详细介绍了iOS二维码的生成代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08

最新评论