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

     抽屉效果

        添加子视图

    *   简单的滑动效果

        * 监听控制器处理事件方法

        * 获取x轴偏移量

        * 改变主视图的frame

    *   利用KVO做视图切换

        往左移动,显示右边,隐藏左边

        往右移动,显示左边,隐藏右边

    *  复杂的滑动效果,PPT讲解(根据手指每移动一点,x轴的偏移量算出当前视图的frame)

        假设x移到320时,y移动到60,算出没移动一点x,移动多少y

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

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

        怎么根据之前的frame,算出当前的frame,touchMove只能拿到之前的frame.

        当前的高度 = 之前的高度 * 这个比例

        缩放比例:当前的高度/之前的高度  (screenH - 2 * offsetY) / screenH

        当前的宽度也一样求。

        y值,计算比较特殊,不能直接用之前的y,加上offsetY,往左滑动,主视图应该往下走,但是offsetX是负数,导致主视图会往上走。

        y = (screenH - 当前的高度)* 0.5

        getCurrentFrameWithOffsetX

    *   定位(滑动松开手指的时候,移动到目标点)

        移动到左右目标点,根据偏移量 = 当前目标点的x - 之前视图的x,计算移动到目标点的frame

        还原:当没有移动到目标点,就把主视图还原。

    *   复位(当主视图不在原始的位置,点击屏幕,恢复原来位置)

        判断手指是否移动,移动的时候就自动定位,不需要手动复位。

    代码实现:

    //
    //  ViewController.m
    //  抽屉效果
    //
    //  Created by wtw on 15/7/20.
    //  Copyright (c) 2015年 wtw. All rights reserved.
    //
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (nonatomic,weak) UIView *leftView;
    @property (nonatomic,weak) UIView *rightView;
    @property (nonatomic,weak) UIView *mainView;
    //复位,定位后点击后会复位
    @property (nonatomic,assign) BOOL isDraging;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //添加子控件
        [self addchildview];
        
        //时刻监听主视图frame的改变
        /**
         *  以后如果需要时刻监听对象的某个属性的改变,就用KVO
         *  给mainView添加一个观察者
         *  addObserver:观察者
         *  forKeyPath:需要监听的属性
         *  options:监听新值的改变
         */
        [self.mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
    }
        //只要监听的属性以改变就会调用
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        //NSLog(@"%@",NSStringFromCGRect(self.mainView.frame));
        
        if (self.mainView.frame.origin.x < 0) {
            //显示右边,隐藏左边
            self.rightView.hidden = NO;
            self.leftView.hidden = YES;
        }else if (self.mainView.frame.origin.x >0) {
            //显示左边,隐藏右边
            self.leftView.hidden = NO;
            self.rightView.hidden = YES;
        }
    }
    
    - (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 yellowColor];
        [self.view addSubview:rightView];
        self.rightView = rightView;
        
        //main
        UIView *mainView = [[UIView alloc]initWithFrame:self.view.bounds];
        mainView.backgroundColor = [UIColor redColor];
        [self.view addSubview:mainView];
        self.mainView = mainView;
        
    }
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        //获取手指
        UITouch *touch = [touches anyObject];
        
        //当前点
        CGPoint curP = [touch locationInView:self.view];
        //上一个点
        CGPoint preP = [touch previousLocationInView:self.view];
        
        //获取手指每移动一下,x轴的偏移量
        CGFloat offsetX = curP.x - preP.x;
        
        //设置当前视图的frame
        self.mainView.frame = [self frameWithOffsetX:offsetX];
        
        //记录下当前正在拖拽
        self.isDraging = YES;
    }
    
    # pragma mark - y反向最大的偏移量
    #define MaxY 60
    
    - (CGRect)frameWithOffsetX:(CGFloat)offsetX {
        
        CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
        CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
        CGFloat offsetY = offsetX * MaxY / screenW;
        
        //获取缩放比例
        CGFloat scale = (screenH - 2 * offsetY) / screenH;
        
        //右边移动的时候的缩放比例
        if (self.mainView.frame.origin.x < 0) {
            scale = (screenH + 2 * offsetY) / screenH;
        }
        
        CGRect frame = self.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;
    }
    
    #pragma mark - 定位功能
    #define targetRX 300
    #define TargetLx -250
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        if (_isDraging == NO && _mainView.frame.origin.x != 0) {
            //复位
            [UIView animateWithDuration:0.25 animations:^{
                self.mainView.frame = self.view.bounds;
            }];
            //下面不需要定位
            return;
        }
        
        //定位功能
        CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
        
        //获取当前主视图的frame
        CGRect frame = self.mainView.frame;
        
        CGFloat target = 0;
        
        if (frame.origin.x > screenW * 0.5) {
            //当主视图的x大于屏幕一半,定位到右边
            target = targetRX;
        }else if (CGRectGetMaxX(self.mainView.frame) < screenW * 0.5) {
            //定位左边
            target = TargetLx;
        }
        
        if(target == 0) {
            //还原
            [UIView animateWithDuration:0.25 animations:^{
                self.mainView.frame = self.view.bounds;
            }];
        }else {
        [UIView animateWithDuration:0.25 animations:^{
            //获取x轴偏移量
            CGFloat offsetX = target - frame.origin.x;
            self.mainView.frame = [self frameWithOffsetX:offsetX];
        }];
            
        }
        //记录下当前正在拖拽
        self.isDraging = NO;
        
    }
    
    
    @end
    
  • 相关阅读:
    Nginx编译安装
    Docker下mysql容器开启binlog日志(保留7天)
    podman
    error: audit:backlog limit exceeded
    64位win2003/win2008系统IIS6.0/7.5配置PHP的方法
    iis7.5安装配置php环境详细清晰教程,三步实现【图文】
    Windows下IIS+PHP 5.2的安装与配置
    无线路由MAC地址过滤安全可靠性讨论
    debian flam3 源码
    debian flam3 依赖文件
  • 原文地址:https://www.cnblogs.com/why-not/p/4663058.html
Copyright © 2011-2022 走看看