抽屉效果

作者: 真一 | 来源:发表于2016-01-29 15:38 被阅读570次

    抽屉效果

    效果图:

    抽屉效果.gif

    第一步:搭建界面

    #define maxY 100
    #define ZZScreenW [UIScreen mainScreen].bounds.size.width
    #define ZZScreenH [UIScreen mainScreen].bounds.size.height
    // MainV定位到右侧的X值
    #define ZZTargetR 225
    // MainV定位到右侧的X值
    #define ZZTargetL -275
    
    #import "ViewController.h"
    
    @interface ViewController ()<UIGestureRecognizerDelegate>
    // 左边的view
    @property (nonatomic, weak) UIView *leftV;
    
    // 右边的view
    @property (nonatomic, weak) UIView *rightV;
    
    // 中间的view
    @property (nonatomic, weak) UIView *mainV;
    
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        // 搭建界面
        [self setUpView];
    }
    
    - (void)setUpView{
        // 添加左边的View
        UIView *leftV = [[UIView alloc] initWithFrame:self.view.bounds];
        // 设置左边view的背景色为蓝色
        leftV.backgroundColor = [UIColor blueColor];
        [self.view addSubview:leftV];
        // 添加右边的View
        UIView *rightV = [[UIView alloc] initWithFrame:self.view.bounds];
        // 设置右边view的背景色为绿色
        rightV.backgroundColor = [UIColor greenColor];
        self.rightV = rightV;
        [self.view addSubview:rightV];
        // 添加中间的View(中间一个最后添加,显示到最外面.)
        UIView *mainV = [[UIView alloc] initWithFrame:self.view.bounds];
        // 设置中间view的背景色为红色
        mainV.backgroundColor = [UIColor redColor];
        self.mainV = mainV;
        [self.view addSubview:mainV];
    }
    @end
    

    第二步.添加手势:

    - (void)viewDidLoad {
        [super viewDidLoad];
        // 搭建界面
        [self setUpView];
        // 创建拖动手势
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
        // 添加手势
        [self.mainV addGestureRecognizer:pan];
    }
    
     // 实现手势方法:
    // 当手指拖动时调用.
    -(void)pan:(UIPanGestureRecognizer *)pan{
        // 获取手指在屏幕上面的偏移量
        CGPoint transP = [pan translationInView:self.mainV];
        // 在这里为什么不用Transform,是因为我们移动时,要改变的尺寸大小.用Transform只能改变它的位置.
        // self.mainV.transform  = CGAffineTransformTranslate(self.mainV.transform, transP.x, 0);
    
        // 计算mainV的Frame
        self.mainV.frame = [self frameWithOffsetX:transP.x];
        // 每次移动时判断当前MainV的x值是大于0还是小于0.如果是大于0 , 显示左边,小于0 显示右边
        if (self.mainV.frame.origin.x > 0) {
            self.rightV.hidden = YES;
        }else if(self.mainV.frame.origin.x < 0){
            self.rightV.hidden = NO;
        }
        // 注意要做复位
        [pan setTranslation:CGPointZero inView:self.mainV];
    }
    
    // 根据偏移量计算mainV的frame.
    - (CGRect)frameWithOffsetX:(CGFloat)offsetX{
        // 取出最原始的Frame
        CGRect frame = self.mainV.frame;
        frame.origin.x += offsetX;
        // 获取屏幕的宽度
    
        // (计算Y值如果下图:找最大值.当Main.x拖动最大的时候,Main.y值也最大.main.x最大为屏幕的宽度)
        // 设定一个最大Y值MaxY为100,正好.当max.x为屏幕的宽度时,最大Y等于100
        // 所以Y值等于 main.y = main.x * maxY / ScreenW;
        // 有可能frame.origin.x有可能是小于0,小于0的话, 得出的Y值就会小于0,小于0就会出现, 红色的View向上走.
        // 对结果取绝对值.
        frame.origin.y =  fabs(frame.origin.x * maxY / screenW);
        // 计算frame的高度(当前Main的高度等于屏幕的高度减去两倍的Y值.)
        frame.size.height = screenH - 2 * frame.origin.y;
        // 返回计算好的frame.
        return frame;
    }
    
    计算Y值.png 计算高度.png

    第三步:当手指松开时做到自动定位.

    // 当手指拖动时调用.
    -(void)pan:(UIPanGestureRecognizer *)pan{
        // 获取手指在屏幕上面的偏移量
        CGPoint transP = [pan translationInView:self.mainV];
    
        // 计算mainV的Frame
        self.mainV.frame = [self frameWithOffsetX:transP.x];
        // 每次移动时判断当前MainV的x值是大于0还是小于0.如果是大于0 , 显示左边,小于0 显示右边
        if (self.mainV.frame.origin.x > 0) {
            self.rightV.hidden = YES;
        }else if(self.mainV.frame.origin.x < 0){
            self.rightV.hidden = NO;
        }
        // 判断手指的状态
        if(pan.state == UIGestureRecognizerStateEnded){
            // 当手指松开时进入执行
            // 记录最终判断结果后.定位的值.
            CGFloat target = 0;
            // 当手指松开,要判断MainV的x值是否大于屏幕的一半.如果大于屏幕一半时, 自动定位到右边一个位置.
            if (self.mainV.frame.origin.x > screenW * 0.5) {
                target = targetR;
            }else if(CGRectGetMaxX(self.mainV.frame) < screenW * 0.5){
                // 当手指松开,要判断MainV的最大的X值是否小于屏幕的一半.如果小于屏幕的一半时, 自动定位到左边的位置.
                target = targetL;
            }
            // 最终定位的x值 - 当前的main.x的值.求出偏移量.使其定位
            CGFloat offsetX = target - self.mainV.frame.origin.x;
            // 根据偏移量设置mainV的frame值
            CGRect frame = [self frameWithOffsetX:offsetX];
            [UIView animateWithDuration:0.25 animations:^{
                 // 伴随动画设置frame
                self.mainV.frame = frame;
            }];
        }
        // 注意要做复位
        [pan setTranslation:CGPointZero inView:self.mainV];
    }
    
    求出偏移量.png

    相关文章

      网友评论

      本文标题:抽屉效果

      本文链接:https://www.haomeiwen.com/subject/uymjkttx.html