转载

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

开门见山,先看效果图:

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

自定义转场动画

自定义 UIViewController Present 样式,shrinking bubble 收缩和扩张的泡沫。动画来源于

https://github.com/andreamazz/BubbleTransition

对此进行了一些改进:

  1. 把 swift 源码翻译成 OC

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

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

BubbleTransition效果图

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

但是。。

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

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

背景添加了一张图片

这就尴尬了 a( ̄3 ̄)a ——

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

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

Reveal结果

中间那一层远大于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;
    5
} 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

觉得不错就点个赞吧

  • 作者:whbalzac

  • 链接:http://www.jianshu.com/p/cff00d300d37

  • 來源:简书

  • 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

正文到此结束
Loading...