我们在开发中有没有遇到弹出一个气泡的缩放视图,起到提示或者引导用户点击的作用?我在开发中就遇到了这样的需求。气泡是要求从某个角弹出变大,然后又缩回到对应的角。动画效果:
写到这我们整理一下思路:
1.首先我们实现简单的缩放功能,就是设置view的transform属性嘛。
- (void)showView {
self.transform = CGAffineTransformMakeScale(0.01, 0.01); self.alpha = 0;
[UIView animateWithDuration:0.3 animations:^{
self.alpha = 1;
self.transform = CGAffineTransformMakeScale(1.05, 1.05);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1f animations:^{ self.transform = CGAffineTransformMakeScale(1, 1);
} completion:^(BOOL finished){ // 恢复原位 self.transform = CGAffineTransformIdentity;
}];
}];
}
- (void)hiddenView {
self.transform = CGAffineTransformMakeScale(1 , 1); [UIView animateWithDuration:0.3 animations:^{ self.alpha = 0;
self.transform = CGAffineTransformMakeScale(0.01 , 0.01);
} completion:^(BOOL finished) {
self.transform = CGAffineTransformIdentity;
self.alpha = 0.0f;
}];
}
2.但是怎么设置动画的起始位置呢?这是我遇到的问题。下面我们开始探索之旅。首先我想到的就是设置这个view.layer.anchorPoint 锚点属性.
什么是anchorPoint呢?老规矩看文档。
You specify the value for this property using the unit coordinate space. The default value of this property is (0.5, 0.5), which represents the center of the layer’s bounds rectangle. All geometric manipulations to the view occur about the specified point. For example, applying a rotation transform to a layer with the default anchor point causes the layer to rotate around its center. Changing the anchor point to a different location would cause the layer to rotate around that new point.
翻译:您可以使用单位坐标空间为该属性指定值。这个属性的默认值是(0.5,0.5),它代表了层的边界矩形的中心。对视图的所有几何操作都发生在指定的点上。例如,使用默认锚点对一个层应用旋转变换会导致该层围绕其中心旋转。将锚点更改为不同的位置会导致层围绕新点旋转。
从这个例如中我们就看到了希望,对这个图层做动画是围绕着这个点展开的。直白点说它就是决定我们视图边界的哪个点在哪个位置,比如说是中心点、左上角的点、左下角、右上角、右下角的点。
但是决定它位置的是哪个属性呢?这就需要再次引入另一个属性view.layer.position。
关于position的文档说明:
The position in the superlayer that the anchor point of the layer's bounds rect is aligned to. Defaults to the zero point
翻译:该层的锚点在超层中的位置。默认值是0。
由此可见这个点是决定着锚点的位置。
通过下图了解一下position和anchorPoint的关系:
写到这里我们是不是就有思路了,首先缩放动画我们有了,我们设置view的锚点为左下角然后再设置position的位置在左下角的点就好了。
但是怎么设置这position的属性呢?
这里就涉及到UIView和Layer的区别与联系了:
UIView:用户交互,界面展示
CALayer:绘制界面,属于QuartzCore框架(跨平台的)
总结:UIView负责处理用户交互,layer负责绘制内容。我们访问和设置
的UIView的这些负责显示的属性实际就是访问和设置layer对应的属性,
只不过UIView把他封装了起来。用一张图说明一下吧。
从图中的红框我们就可以看出了,view的center属性就是和layer中的position对应的。这样我们修改view的center属性就修改了layer的position了。但是有的人问了我可以直接设置这个layer的position属性不可以吗?其实是可以的,这里说明一下,要是你布局用的是frame的方式你用设置center和position的方式都是可以的。但是你要是用Masnory的话直接设置View的center属性更加的方便。
于是我们就可以总结一下:
假设view 的frame为:(0,0,100,80)
相当于:(CGRectGetMinX(rect),CGRectGetMinY(rect),CGRectGetWidth(rect),CGRectGetHeight(rect))
要想气泡从某角开始缩放动画的设置:(示意代码)
左上角:
view.center = CGPointMake(0, 0);
view.layer.anchorPoint = CGPointMake(0, 0);
左下角:
view.center = CGPointMake(0, 0 + 80);
view.layer.anchorPoint = CGPointMake(0, 1);
右下角:
view.center = CGPointMake(0 + 100, 0 + 80);
view.layer.anchorPoint = CGPointMake(1, 1);
右上角:
view.center = CGPointMake(0 + 100, 0);
view.layer.anchorPoint = CGPointMake(1, 0);
中心点:
view.center = CGPointMake(0 + 100 / 2, 0 + 80 / 2);
view.layer.anchorPoint = CGPointMake(0.5, 0.5);
左中:
view.center = CGPointMake(0 , 0 + 80 / 2);
view.layer.anchorPoint = CGPointMake(0, 0.5);
右中:
view.center = CGPointMake(0 + 100, 0 + 80 / 2);
view.layer.anchorPoint = CGPointMake(1, 0.5);
上中:
view.center = CGPointMake(0 + 100 / 2, 0);
view.layer.anchorPoint = CGPointMake(0.5, 0);
下中:
view.center = CGPointMake(0 + 100 / 2, 0 + 80);
view.layer.anchorPoint = CGPointMake(0.5, 1);
说了这么多了,不上个demo显得没有诚意。您拿好,如果帮到您了支持一下,哪里做的不好请多多指教。https://github.com/WarmLGZ/GZPopScaleView
参考文章:
关于对position和anchorPoint的关系理解:
https://www.jianshu.com/p/56e61e0de56c
https://www.jianshu.com/p/94ba4de209ed
关于对transform的理解: