zoukankan      html  css  js  c++  java
  • iOS实现抽屉效果

    抽屉效果

    在iOS中非常多应用都用到了抽屉效果,比如腾讯的QQ,百度贴吧…

    这里写图片描写叙述———这里写图片描写叙述

    1. 终于效果例如以下图所看到的

    这里写图片描写叙述———这里写图片描写叙述

    2.实现步骤

    1.開始启动的时候。新建3个不同颜色的View的

    1.设置3个成员属性。记录三种颜色的View

    @property (nonatomic,weak) UIView* redView;
    @property (nonatomic,weak) UIView* greenView;
    @property (nonatomic,weak) UIView* blueView;
    

    2.初始化3个View

    - (void)setUpthreeViews
    {
        UIView *blueView = [[UIView alloc]initWithFrame:self.view.bounds];
        blueView.backgroundColor = [UIColor blueColor];
        [self.view addSubview:blueView];
        _blueView = blueView;
    
        UIView *greenView = [[UIView alloc]initWithFrame:self.view.bounds];
        greenView.backgroundColor = [UIColor greenColor];
        [self.view addSubview:greenView];
        _greenView = greenView;
    
        UIView *redView = [[UIView alloc]initWithFrame:self.view.bounds];
        redView.backgroundColor = [UIColor redColor];
        [self.view addSubview:redView];
        _redView = redView;
    }
    

    2.实现滑动的效果

    1.通过-(void)touchesMoved:(NSSet )touches withEvent:(UIEvent )event方法来获得当前点和初始点,从而计算出偏移量,然后计算redView的frame的值:

    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *touch = [touches anyObject];
        //获得当前点
        CGPoint currentPoint = [touch locationInView:_redView];
        //获得起点
        CGPoint prePoint = [touch previousLocationInView:_redView];
        //计算在x轴方向上的偏移量
        CGFloat moveX = currentPoint.x - prePoint.x;
        //然后通过在x轴上的偏移量。计算redView的frame
        _redView.frame = [self framWithOffsetX:moveX];
    }
    1. 假设x移到320时。y移动到60,算出每移动一点x,移动多少y

    2. offsetY = offsetX * 600 / 320 手指每移动一点,x轴偏移量多少,y偏移多少

    3. 为了好看。x移动到320。距离上下的高度须要保持一致。并且有一定的比例去缩放他的尺寸。

    4. touchMove仅仅能拿到之前的frame.当前的高度 = 之前的高度 * 这个比例
      缩放比例:当前的高度/之前的高度 (screenH - 2 * offsetY) / screenH。
      当前的宽度保持不变即可。
    5. y值,计算比較特殊,不能直接用之前的y,加上offsetY,往左滑动。主视图应该往下走,可是offsetX是负数,导致主视图会往上走。所以须要推断是左滑还是右滑
    - (CGRect)framWithOffsetX:(CGFloat)offsetX
    {
        //计算在y轴方向上的偏移量
        CGFloat offsetY = offsetX/SCREENWIDTH * MAXYOFFSET;
        //依据y方向的偏移量计算缩放比例
        CGFloat scale = (SCREENHEIGHT - 2*offsetY)/SCREENHEIGHT;
        //假设x < 0表示左滑
        if (_redView.frame.origin.x < 0) {
            scale = (SCREENHEIGHT + 2*offsetY)/SCREENHEIGHT;
        }
    
        CGRect frame = _redView.frame;
        //计算滑动之后的frame
        CGFloat height = frame.size.height*scale;
        CGFloat width  = frame.size.width;
        CGFloat x = frame.origin.x + offsetX;
        CGFloat y = (SCREENHEIGHT- height)* 0.5;
    
        return CGRectMake(x, y, width, height);
    }
    
    

    2.通过KVO来监听redView的frame的变化,从而推断redView是左滑还是右滑。往左移动。显示右边,隐藏左边 往右移动。显示左边。隐藏右边

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self setUpthreeViews];
    
        // 利用KVO时刻监听_redView.frame改变
        // Observer:谁须要观察
        // KeyPath:监听的属性名称
        // options: NSKeyValueObservingOptionNew监听这个属性新值
        [_redView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    // 仅仅要监听的属性有新值的时候。仅仅要redView.frame一改变就会调用
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if (self.redView.frame.origin.x > 0) {
            _greenView.hidden = NO;
        } else if(self.redView.frame.origin.x < 0){
            _greenView.hidden = YES;
        }
    }
    
    // 当对象销毁的时候,一定要移除观察者
    - (void)dealloc
    {
        [_redView removeObserver:self forKeyPath:@"frame"];
    }
    

    3.设置触摸结束的时候。redView的frame。假设redView側滑没有到屏幕的一半,则自己主动返回到初始位置。

    假设超过屏幕的一半,则停留在一个新的位置

    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        CGFloat xPos = _redView.frame.origin.x;
        //大于屏幕的一半进入新的位置
        if (xPos > SCREENWIDTH*0.5) {
            [UIView animateWithDuration:0.5 animations:^{
                self.redView.frame = [self framWithBigThanX:ENDRIGHTX];
            }];
            return ;
        }
        //小于屏幕的一半。大于屏幕负一半的时候,则恢复到初始状态
        if (xPos < SCREENWIDTH*0.5 && xPos > -SCREENWIDTH*0.5) {
            [UIView animateWithDuration:0.5 animations:^{
                self.redView.frame = [UIScreen mainScreen].bounds;
            }];
            return ;
        }
        //xPos < -SCREENWIDTH*0.5的时候,进入新的位置
        [UIView animateWithDuration:0.5 animations:^{
            self.redView.frame =  [self framWithSmallThanX:ENDLEFTX];
        }];
    
    }
    
    
    - (CGRect)framWithBigThanX:(CGFloat)offsetX
    {
    
        CGFloat offsetY = offsetX/SCREENWIDTH * MAXYOFFSET;
        CGFloat scale = (SCREENHEIGHT - 2*offsetY)/SCREENHEIGHT;
    
        CGFloat height = SCREENHEIGHT*scale;
        CGFloat width  = SCREENWIDTH;
        CGFloat x = offsetX;
        CGFloat y = (SCREENHEIGHT- height)* 0.5;
    
        return CGRectMake(x, y, width, height);
    }
    
    - (CGRect)framWithSmallThanX:(CGFloat)offsetX
    {
        CGFloat offsetY = offsetX/SCREENWIDTH * MAXYOFFSET;
        CGFloat scale = (SCREENHEIGHT + 2*offsetY)/SCREENHEIGHT;
    
        CGFloat height = SCREENHEIGHT*scale;
        CGFloat width  = SCREENWIDTH;
        CGFloat x = offsetX;
        CGFloat y = (SCREENHEIGHT- height)* 0.5;
    
        return CGRectMake(x, y, width, height);
    }
    
  • 相关阅读:
    HDU 1556 差分,前缀和
    Full permutation
    PAT B1029
    字串简介
    阵列(3)
    完形填空
    关于c的比较
    19 阵列的复制
    switch述句
    阵列变数(2)
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7118701.html
Copyright © 2011-2022 走看看