iOS WHBubbleTransition(自定义VC转场动画)

开门见山,先看效果图:

自定义转场动画.gif

自定义 UIViewController Present 样式,shrinking bubble 收缩和扩张的泡沫。动画来源于
https://github.com/andreamazz/BubbleTransition

对此进行了一些改进:

1. 把 swift 源码翻译成 OC

2. 改进了一些动画机制,具体如下

BubbleTransition效果图.gif

从它给的效果图来看,升缩的效果非常赞 (~ ̄▽ ̄~) ——

但是。。

聪明的你可能已经看见了,图中的两个 ViewController 背景就是纯色,上面没任何其他 View,所以显得效果很赞。接下来我们看一下加上 View 的效果——

背景添加了一张图片.gif
这就尴尬了 a( ̄3 ̄)a ——

利用 Reveal 我们看看 View 的层次结构。

Reveal结果.png

中间那一层远大于375 x 667的 View 很引人注目呀 (#-.-)——

再来看看代码:

//计算一些关键point和frame
CGPoint originalCenter = presentedControllerView.center;
CGSize originalSize = presentedControllerView.frame.size;
CGFloat lengthX = fmax(self.startPoint.x, originalSize.width - self.startPoint.x);
CGFloat lengthY = fmax(self.startPoint.y, originalSize.height - self.startPoint.y);
CGFloat offset = sqrt(lengthX * lengthX + lengthY * lengthY) * 2;
CGSize size = CGSizeMake(offset, offset);

//上图中的大View,先缩小到最小,再用UIView的动画变大,设置cornerRadius变成圆,然后漏出下面的VC的view
self.bubble = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
self.bubble.layer.cornerRadius = size.height/2.0f;
self.bubble.center = self.startPoint;
self.bubble.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);
self.bubble.backgroundColor = self.bubbleColor;
[containerView addSubview:self.bubble];

//上层VC的View
presentedControllerView.center = self.startPoint;
presentedControllerView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);
presentedControllerView.alpha = 0;
[containerView addSubview:presentedControllerView];

[UIView animateWithDuration:self.duration animations:^{
    self.bubble.transform = CGAffineTransformIdentity;
    presentedControllerView.transform = CGAffineTransformIdentity;
    presentedControllerView.alpha = 1;
    presentedControllerView.center = originalCenter;
    
} completion:^(BOOL finished) {
    [transitionContext completeTransition:finished];
}];

注释中解释了动画原因。主要的原理是View的层级关系,通过上层 bubble 这个 View,慢慢变大,形成圆扩大的动画。但有一个前提是,下层的 View的背景色和bubble同色,混合之后,才能形成完整的动画,一旦下层 View 有“噪点”,这个动画就失效了。就像上面的gif展示的一样。

改进

既然原代码是通过上下层 View 来实现,那让咱们换个思路,只需要修改一点点代码就可以——

iOS不是还有一个好玩的东西,叫做 maskView 的吗?
CGPoint originalCenter = presentedControllerView.center;
CGSize originalSize = presentedControllerView.frame.size;
CGFloat lengthX = fmax(self.startPoint.x, originalSize.width - self.startPoint.x);
CGFloat lengthY = fmax(self.startPoint.y, originalSize.height - self.startPoint.y);
CGFloat offset = sqrt(lengthX * lengthX + lengthY * lengthY) * 2;
CGSize size = CGSizeMake(offset, offset);

self.bubble = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
self.bubble.backgroundColor = [UIColor redColor];
self.bubble.layer.cornerRadius = size.height/2.0f;
self.bubble.center = self.startPoint;
self.bubble.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);
//将上层 bubble 当做下层 View 的 maskView
containerView.maskView = self.bubble; 

presentedControllerView.center = originalCenter;
[containerView addSubview:presentedControllerView];

[UIView animateWithDuration:self.duration animations:^{
    self.bubble.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
    [transitionContext completeTransition:finished];
}];

Github链接:

https://github.com/Balzac646729740/WHBubbleTransition

觉得不错就点个赞吧😀😀
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,828评论 2 45
  • 太长了,还是转载吧...今天在看博客的时候,无意中发现了@Trinea在GitHub上的一个项目Android开源...
    庞哈哈哈12138阅读 20,383评论 3 283
  • 先上一张奕奕自己叠的衣服的图,爸爸说这是奕奕的房间,奕奕的衣服叠好了可以放在他自己喜欢的地方,然后奕奕小盆友就看好...
    辛馨阅读 170评论 0 0
  • 没有目的,没有方向,想要一场说走就走的散步。外面的环境不比屋内温暖,但空气却也不比屋内厚重,也许有些不适这清晨的寒...
    不懂wz阅读 401评论 0 0
  • 因为我对虚拟世界爱的深沉。 并不是我故意甩锅,这还真不完全是我一个人的锅,有记忆以来就被不断强化安静乖巧爱读书的宅...
    无良印品阅读 343评论 0 0

友情链接更多精彩内容