美文网首页
简单实现折叠效果

简单实现折叠效果

作者: 其实朕是一只程序猿 | 来源:发表于2016-05-01 18:27 被阅读333次
    折叠效果.gif

    界面分析

    • 手指在图片上拖拽,图片的上半部分能够跟随手指的移动产生一个旋转的效果.
    • 向下拖拽的时候,图片的下半部分会有阴影产生.
    • 在手指松开的时候,恢复到初始状态,并且产生1个回弹效果.

    界面实现

    在一个imageView 上面对图片进行变换操作,显然不太现实.可以使用两个imageView上下拼接在一起,使用1个大view作为容器装置两个imageView.

    Snip20160501_4.png

    给这个view绑定类

    创建折叠view的类

    所以现在必须在上面的imageView显示图片的上半部分,在下面的imageView显示图片的下半部分.

    有两种方式可以实现

    • 第一种方式

    在storyboard中设置顶部imageView的contentMode 为top,底部imageView的contentMode为bottom.

    Snip20160501_7.png

    这样设置完之后看起来就像是拼接成的一整张图片了.但是使用这种方式设置完之后,由于图片的大小是超过imageView的大小的.并且旋转的坐标轴是整个view的中心位置,所以使用这种方式凭借的话还需要做一些配置

    - (void)awakeFromNib {
        
        self.topImageView.layer.masksToBounds = YES;
        
        self.bottomImageView.layer.masksToBounds = YES;
        
        //设置锚点
        self.topImageView.layer.anchorPoint = CGPointMake(0.5, 1);
    }
    
    

    由于重新设置了锚点 所以此时运行程序界面会变成这样

    修改锚点之后

    重新布局使界面正确正确显示

    - (void)layoutSubviews {
        
        [super layoutSubviews];
    
        self.topImageView.layer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
    }
    

    修改完之后

    修改完之后
    • 2 第二种方式比较简单.使用layer自带的一个属性contentsRect .
      不用设置contentMode属性,只需要在
    - (void)awakeFromNib {
        
        //contentsRect 取值范围为 0 - 1
        self.topImageView.layer.contentsRect = CGRectMake(0, 0, 1, 0.5);
        
        self.bottomImageView.layer.contentsRect = CGRectMake(0, 0.5, 1, 0.5);
    //设置锚点 让topImageView可以绕着底部旋转
        self.topImageView.layer.anchorPoint = CGPointMake(0.5, 1);
        //给foldView 添加拖拽手势
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
        
        [self addGestureRecognizer:pan];
    
    //  利用`CAGradientLayer`(渐变图层)制作阴影效果,添加到底部视图上,并且一开始需要隐藏,在拖动的时候慢慢显示出来。
    //  颜色应是由`透明到黑色`渐变,表示阴影从无到有。
        CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    
        //渐变图层的颜色组属性
        gradientLayer.colors = @[(id)[UIColor clearColor].CGColor,(id)[UIColor blackColor].CGColor];
        //设置图层frame
        gradientLayer.frame = self.bottomImageView.bounds;
        //设置图层不透明度
        gradientLayer.opacity = 0;
        //设置渐变的起点 取值范围为 0 - 1
        gradientLayer.startPoint = CGPointMake(0.5, 1);
        //设置渐变终点
        gradientLayer.endPoint = CGPointMake(0.5, 0);
        //添加图层
        [self.bottomImageView.layer addSublayer:gradientLayer];
        //给foldView添加属性引用图层
        self.gradientLayer = gradientLayer;
    }
    //重新布局
    - (void)layoutSubviews {
        [super layoutSubviews];
    
        self.topImageView.layer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height * 0.5);
    }
    

    实现拖拽监听方法

    
    - (void)pan:(UIPanGestureRecognizer *)pan {
        
        //手指拖拽的距离
        CGPoint offset = [pan translationInView:self];
        //宽度
        CGFloat height = self.bounds.size.height *  0.5;
         //  计算Y轴每偏移一点,需要旋转多少角度,angle = offsetY  * M_PI / width;
        CGFloat angle = offset.y / height * M_PI ;
        // 在拖动的时候计算不透明度值,假设拖动bottomImageView的一半时,阴影完全显示,不透明度应该为1,因此 opacity = y轴偏移量 * 1 /  200.0;
        CGFloat opacity = offset.y * 1.0 / height;
        if(pan.state == UIGestureRecognizerStateEnded) {//拖拽停止的时候
            //弹簧动画
            [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:9 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                //手指停止拖拽的时候重置图层形变
                self.topImageView.layer.transform = CATransform3DIdentity;
            } completion:^(BOOL finished) {
                
            }];
            //将渐变层的不透明度改为0(透明).
            self.gradientLayer.opacity = 0;
            
        }else {
            //初始化
            CATransform3D trans = CATransform3DIdentity;
            //设置M34就有立体感(近大远小)。 -1 / z ,z表示观察者在z轴上的值,z越小,看起来离我们越近,东西越大。
            trans.m34 =  1 / 1000.0;
            //设置绕x轴旋转
            self.topImageView.layer.transform = CATransform3DRotate(trans, angle, 1, 0, 0);
            //设置不透明度
            self.gradientLayer.opacity = opacity;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:简单实现折叠效果

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