IOS通过CGAffineTransform实现常见的动画效果原创
金蝶云社区-honey缘木鱼
honey缘木鱼
10人赞赏了该文章 751次浏览 未经作者许可,禁止转载编辑于2019年02月23日 16:59:07

 在开发中,我们经常会遇到视图的显示,隐藏等功能,如果仅仅用Hide属性控制,会显得很生硬,用户体验较差,所以可以考略通过CGAffineTransform来实现,下面就以我们公司UI设计提出的两种动画效果为例,以此说明用CGAffineTransform如何实现。


一.点击列表按钮展示,隐藏动画

    1. UI效果图如下:

屏幕快照 2019-02-23 下午3.51.06.png

   

2.需求:点击编辑时,分别依次展开更改信息,下架,删除,点击列表其他部分或是滑动列表时,删除,下架,更改信息分别依次收缩,展开,收缩都要有相应的动画效果。


 3. 具体实现的关键代码:

//展开动画

   [UIView beginAnimations:nil context:nil];

    _upBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity,1,1);

    _upBtn.frame = CGRectMake((kScreenWidth-20)-80, 0, 40, 85);

    _delectBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity,1,1);

    _delectBtn.frame = CGRectMake((kScreenWidth-20)-120, 0, 40, 85);

     [UIView commitAnimations];


//关闭动画

   [UIView beginAnimations:nil context:nil];

    _upBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity,1,1);

    _upBtn.frame = CGRectMake((kScreenWidth-20)-40, 0, 40, 85);

    _delectBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity,1,1);

    _delectBtn.frame = CGRectMake((kScreenWidth-20)-40, 0, 40, 85);

    [UIView commitAnimations];


4. 详细讲解

   初始化: CGAffineTransform  transform = CGAffineTransformIdentity;

   CGAffineTransformMakeScale实现以初始位置为基准,在x轴方向上缩放1倍,在y轴方向上缩放1倍(显示)

    

二.常见的底部弹出框显示,隐藏动画

   1.UI设计图:


屏幕快照 2019-02-23 下午4.10.59.png

 2.需求:为增强用户体验,弹出框出现和隐藏时需要一个平移的动画效果。


 3. 具体实现的关键代码:

    //显示动画


- (void)show:(BOOL)animated

{

    if (animated)

    {

        self.transform = CGAffineTransformTranslate(self.transform,0,self.selfHeight);

        __weak RechargeSMSView *weakSelf = self;

        [UIView animateWithDuration:.3 animations:^{

            weakSelf.transform = CGAffineTransformTranslate(weakSelf.transform,0,0);

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:.3 animations:^{

                weakSelf.transform = CGAffineTransformIdentity;

            }];

        }];

    }

}

//隐藏动画

- (void)hide:(BOOL)animated

{

    [self endEditing:YES];

    if (self.bGView != nil) {

        __weak RechargeSMSView *weakSelf = self;

        [UIView animateWithDuration: animated ?0.3: 0 animations:^{

            weakSelf.transform = CGAffineTransformTranslate(weakSelf.transform,0,self.selfHeight);

        } completion:^(BOOL finished) {

            [weakSelf.bGView removeFromSuperview];

            [weakSelf removeFromSuperview];

            weakSelf.bGView=nil;

        }];

    }

}


4. 详细讲解  

CGAffineTransformMakeTranslation实现以初始位置为基准,在x轴方向上平移x单位,在y轴方向上平移y单位,显示或隐藏时只需在Y轴上平移所显示的弹出框高度即可!


三.总结

从上面两个动画实现效果中可以看出,分别是通过CGAffineTransform的CGAffineTransformMakeScale(缩放)、CGAffineTransformMakeTranslation(移动)来实现的。那么CGAffineTransform的实现原理是什么样的呢?


四.CGAffineTransform实现原理

  CGAffineTransform形变是通过"仿射变换矩阵"来控制的,其中平移是矩阵相加,旋转与缩放则是矩阵相乘,为了合并矩阵运算中的加法和乘法,引入了齐次坐标的概念,它提供了用矩阵运算把二维、三维甚至高维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法.CGAffineTransform形变就是把二维形变使用一个三维矩阵来表示,其中第三列总是(0,0,1),形变通过前两列来控制,系统提供了CGAffineTransformMake结构体来控制形变。


// 格式CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)

 

该三维变换矩阵如下

 

 

通过变换矩阵左乘向量,将空间中的一个点集从一个坐标系变换到另一个坐标系中,计算方式如下

 

 

 


由此可知,其中tx用来控制在x轴方向上的平移,ty用来控制在y轴方向上的平移;a用来控制在x轴方向上的缩放,d用来控制在y轴方向上的缩放;abcd共同控制旋转。

  • 平移CGAffineTransformMakeTranslation原理

self.demoImageView.transform = CGAffineTransformMakeTranslation(100, 100);self.demoImageView.transform = CGAffineTransformMake(1, 0, 0, 1, 100, 100);
  • 缩放CGAffineTransformMakeScale原理

self.demoImageView.transform = CGAffineTransformMakeScale(2, 0.5);self.demoImageView.transform = CGAffineTransformMake(2, 0, 0, 0.5, 0, 0);
  • 旋转CGAffineTransformMakeRotation原理

self.demoImageView.transform = CGAffineTransformMakeRotation(M_PI*0.5);
self.demoImageView.transform = CGAffineTransformMake(cos(M_PI * 0.5), sin(M_PI * 0.5), -sin(M_PI * 0.5), cos(M_PI * 0.5), 0, 0);
  • 初始状态CGAffineTransformIdentity原理

self.demoImageView.transform = CGAffineTransformIdentity;self.demoImageView.transform = CGAffineTransformMake(1, 0, 0, 1, 0, 0);



注:本篇独发金蝶云社区。

赞 10