因为项目需求,需要如下这样一个简单的动画效果:
####单个控件 这个动画效果,如果对控件使用UIView
的block动画,设置控件的Frame值,是可以实现的.
比如下面这个效果:
我们可以代码来简单实现上面的效果:- (void)viewDidLoad {
[super viewDidLoad];
self.btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
[self.btn setImage:[UIImage imageNamed:@"1"] forState:UIControlStateNormal];
[self.view addSubview:self.btn];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[UIView animateWithDuration:1.0 animations:^{
self.btn.frame = CGRectMake(100, 300, 200, 0);
}];
}
复制代码
####如果是多个控件呢? 我们比葫芦画瓢,把btn放到一个View当中,我们再对View使用一个UIView的block动画. 首先看下代码:
- (void)viewDidLoad {
[super viewDidLoad];
self.outView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-44)];
self.outView.backgroundColor = [UIColor redColor];
self.btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
[self.btn setImage:[UIImage imageNamed:@"1"] forState:UIControlStateNormal];
[self.outView addSubview:self.btn];
[self.view addSubview:self.outView];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[UIView animateWithDuration:1.0 animations:^{
self.outView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height-44, [UIScreen mainScreen].bounds.size.width, 0);
}];
}
复制代码
然后我们看下效果:
红色的View发生了形变,但是里面的控件并没有跟着缩放. 看来这个方案不行. 我想,应该可以用CGAffineTransform来进行一个动画缩放. 然后把上面self.outView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height-44, [UIScreen mainScreen].bounds.size.width, 0);
替换成
self.outView.layer.affineTransform = CGAffineTransformScale(self.outView.layer.affineTransform, 1.0, 0.001);
(这里的sy如果为0的话,会直接消失.)然后动画效果是下面这样的:
很明显不符合我们的要求,我想要控件的底部不动,从上面开始进行压缩下来.
####anchorPoint, position, CGAffineTransform 是的,通过这三个东西,来实现,首先我们上代码和实现图,然后再进行分析.
- (void)viewDidLoad {
[super viewDidLoad];
self.outView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-44)];
self.outView.backgroundColor = [UIColor redColor];
self.btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
[self.btn setImage:[UIImage imageNamed:@"1"] forState:UIControlStateNormal];
[self.outView addSubview:self.btn];
[self.view addSubview:self.outView];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//注意这里不能使用self.outView.frame因为Frame会随着控件的变化而变化.
//这样就导致了layer的position的位置不准确了.
CGFloat positionX = 0.5*self.outView.bounds.size.width;
CGFloat positionY = 1.0*self.outView.bounds.size.height;
self.outView.layer.anchorPoint = CGPointMake(0.5, 1);
self.outView.layer.position = CGPointMake(positionX, positionY);
[UIView animateWithDuration:1.0 animations:^{
self.outView.layer.affineTransform = CGAffineTransformScale(self.outView.layer.affineTransform, 1, 0.001);
}];
}
复制代码
效果:
这下就完美了,红色的View和它里面的子控件一起进行了缩放. 关键点就那两行代码,设置了outView
的anchor和position. 关于anchor和position的文章,网上有很多介绍的.我这里就不再进行赘述. position的x = view.bounds.size.width * anchorPoint.x; x = view.bounds.size.height * anchorPoint.y; 当你改变anchorPoint的值的时候,要确保position的值也进行了相应的改变,否则会产生View的位置不正确.