iOS压缩动画 CGAffineTransform

因为项目需求,需要如下这样一个简单的动画效果:


####单个控件 这个动画效果,如果对控件使用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的位置不正确.

转载于:https://juejin.im/post/5a376c5451882560b6526ac6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值