简单实现折叠效果

2016-05-01  本文已影响333人  其实朕是一只程序猿
折叠效果.gif

界面分析

界面实现

在一个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);
}

修改完之后

修改完之后
- (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;
    }
}

上一篇下一篇

猜你喜欢

热点阅读