iOS使用动画连贯过渡界面转换

版权声明:大熊猫猪·侯佩原创或翻译作品.谢绝转载! hopy https://blog.csdn.net/mydo/article/details/85200002

本博向大家演示如何通过添加动画,为原有界面元素变换增加连贯的过渡效果.为UI代码一丝动态与活力感.

缘起

第三方的一个图片裁剪器,拿过来做了几点修改:

  • 将其封装到动态库中,方便集成
  • 扩充了一些功能,比如等待菊花和是否允许进行裁剪等
  • 用封装好的动态库创建了一个ImageCropRow类,这样就可以在Eureka中方便的使用了

大致就是如此,细节不必深究,现在的效果是这个样子的:

在这里插入图片描述

总体符合本猫的要求,不过感觉好像少了点神马…

在这里插入图片描述

貌似感觉选择不同裁剪比例时,裁剪区域改变有点唐突,有点僵硬…

我们接下来的工作就是试图改变这种情况,使裁剪区域改变的更顺畅一些.

救兵甲:View动画

我们首先来完成白色裁剪框外观改变的动画,因为裁剪框是用若干View拼凑而成的,所以我们可以直接用视图动画来做改变的效果.

找到裁剪比例选择按钮的回调,里面有一句:

_tkImageView.cropAspectRatio = currentProportion;

我们将其修改为如下代码:

[UIView animateWithDuration:0.5 animations:^{
    _tkImageView.cropAspectRatio = currentProportion;
];

神马!?这就可以了么???

别急,我们看一下修改后的效果:

在这里插入图片描述

很赞是不是?

虽然白色裁剪框有了动画改变效果,但细心的你可能发现后面裁剪区域的改变并没有动画,这显得非常不协调.

别急我们马上来完善它!

救兵乙:Layer动画

首先进入_tkImageView.cropAspectRatio的setter里看看:

- (void)setCropAspectRatio:(CGFloat)cropAspectRatio {
    _cropAspectRatio = MAX(cropAspectRatio, 0);
    [self resetCropAreaByAspectRatio];
}

可以看到裁剪区域的改变的关键可能在resetCropAreaByAspectRatio方法中,进去看看,不出所料它调用了如下方法:

[self resetCropTransparentArea];

继续跟进该方法,看看它到底干了神马:

- (void)resetCropTransparentArea {
    UIBezierPath *path = [UIBezierPath bezierPathWithRect: _imageView.bounds];
    UIBezierPath *clearPath = [[UIBezierPath bezierPathWithRect: _cropAreaView.frame] bezierPathByReversingPath];
    [path appendPath: clearPath];
    CAShapeLayer *shapeLayer = (CAShapeLayer *)_cropMaskView.layer.mask;
    if(!shapeLayer) {
        shapeLayer = [CAShapeLayer layer];
        [_cropMaskView.layer setMask: shapeLayer];
    }
    shapeLayer.path = path.CGPath;
}

重点就是最后一句:修改裁剪区域的遮罩(mask)的形状,从而改变裁剪区域的形状!

因为mask是Layer上的概念,所以我们需要使用层动画让它动起来,在上面最后一句前面加上如下一段代码:

	CABasicAnimation *pathAnim = [CABasicAnimation animationWithKeyPath:@"path"];
        pathAnim.duration = .5;
        pathAnim.toValue = [NSValue valueWithPointer:path.CGPath];
        pathAnim.removedOnCompletion = TRUE;
        pathAnim.fillMode = kCAFillModeForwards;
        [shapeLayer addAnimation:pathAnim forKey:nil];

编译运行,效果如下:

在这里插入图片描述

可以明显发现,裁剪区域变换的过渡更加顺畅和自然.

美美哒…

在这里插入图片描述

等等…如果看到上面演示的最后,你会发现当你手动拖动裁剪框时,裁剪区域变化也会有动画效果,这就有些让人感到怪异了.所以还得做一点调整动作!

收尾动作

将原方法签名改为如下名称:

- (void)resetCropTransparentAreaWithAnimation:(BOOL)withAnimation {

}

然后根据是否动画,将原来Layer动画包含起来.最后替换手动修改裁剪区域处的调用方式:不使用动画即可.

好了,这就是全部内容了,大家可以将最后的结果和之前没有动画比较一下,看看有哪些不同的感觉.

😉

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试