动画创建及transfrom属性

OC语言中,动画创建有两种方法

1)头尾式动画,非常少用,了解即可。例如:

    /*动画的第一种实现方法:头尾式动画*/
    // 开始动画
    [UIView beginAnimations:nil context:nil];
    
    // 设置动画时间
    [UIView setAnimationDuration:2];
    
    // ------------------动画代码---------------
    self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, 10, 100);
    
    // 提交动画
    [UIView commitAnimations];

2)Block动画。最常用,必须掌握相关参数含义。例如

    /*Block动画*/
    /*
     第一个参数:动画执行时间
     第二个参数:动画延迟执行时间
     第三个参数:弹簧阻尼系数 取值范围 0 - 1 ; 0:没有阻力  1:阻力最大,没有弹簧效果
     第四个参数:初速度
     第五个参数:动画效果
     第六个参数:动画的block代码
     第七个参数:动画执行完成后执行的block
     */
    [UIView animateWithDuration:3 //表示整个动画时间3s
                          delay:0 //表示没有延迟
         usingSpringWithDamping:1 //表示阻力最大,无弹簧效果
          initialSpringVelocity:1 //表示初速度为1
                        options:UIViewAnimationOptionCurveLinear //线性
                     animations:^{
                         self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, 10, 100);//动画
                     }
                     completion:^(BOOL finished) {
                         NSLog(@"飘过去了。。。”); //动画执行完毕后执行的语句
                     }];

有一些循环动画。例如如下代码(支付宝咻一咻功能部分代码)

    for (int i = 0; i < 6; i++) {
        // 创建光环视图
        UIView *circleView = [self createCircleView];      
        // 动画放大:
        [UIView animateWithDuration:3 delay:0.5 * i options:UIViewAnimationOptionCurveLinear animations:^{
            //动画代码
            //[UIView setAnimationRepeatCount:MAXFLOAT];//这一句可以无限循环
            circleView.transform = CGAffineTransformMakeScale(10, 10);
            //透明度。一个属性是否能放在动画代码中,可参阅UIView中对属性是否标注animatable。
            circleView.alpha = 0;
        } completion:^(BOOL finished) {
            [circleView removeFromSuperview];//动画执行完毕后,要删除创建的视图
        }];


动画中经常用到UIView的一个很重要属性:transform。

@property(nonatomic) CGAffineTransform transform;

仿射变换常用的方法有:

    //创建一个仿射变换
    //Returns an affine transformation matrix constructed from values you provide.
    CGAffineTransform CGAffineTransformMake ( CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty );
    
    //旋转变换 angle为弧度
    //Returns an affine transformation matrix constructed from a rotation value you provide.
    CGAffineTransformMakeRotation(<#CGFloat angle#>)
    //Returns an affine transformation matrix constructed by rotating an existing affine transform.
    CGAffineTransformRotate(<#CGAffineTransform t#>, <#CGFloat angle#>)
    
    //缩放变换 sx、sy为缩放比率
    //Returns an affine transformation matrix constructed from scaling values you provide.
    CGAffineTransformMakeScale(<#CGFloat sx#>, <#CGFloat sy#>)
    //Returns an affine transformation matrix constructed by scaling an existing affine transform.
    CGAffineTransformScale(<#CGAffineTransform t#>, <#CGFloat sx#>, <#CGFloat sy#>)
    
    //平移变换,tx、ty分别为水平 和 垂直 偏移量
    //Returns an affine transformation matrix constructed from translation values you provide.
    CGAffineTransformMakeTranslation(<#CGFloat tx#>, <#CGFloat ty#>)
    //Returns an affine transformation matrix constructed by translating an existing affine transform.
    CGAffineTransformTranslate(<#CGAffineTransform t#>, <#CGFloat tx#>, <#CGFloat ty#>)
    
    //单位矩阵,常量,用于还原transform
    CGAffineTransformIdentity


相关知识点:

1、图像变换中注意frame与bounds的区别

1)frame 与 bounds 都是UIView中的CGRect 属性,都有(origin,size)组成

2)修改frame.size,UIView是以左上角为中心点变化。(UIView的frame.orign没有变化,UIView的bounds属性是否发生变化??)

      修改bounds,size,UIView是以UIView的center为中心点变化的。(UIView的frame.orign发生变化,frame.size无变化,bounds.size变化,bounds.orign有变化)


    //结论
    //修改frame.size,图像改变
    //      frame.orign不变。frame.size变化是以UIView的frame.orign为轴变动,因此frame.orign不动,在superView坐标系中的位置也没变
    //      frame.size改变
    //      bounds.orign不变,自身坐标系始终不变
    //      bounds.size改变,因为bounds.size与frame.size是相互影响的,修改一个,另一个会发生改变


    //结论:
    //修改bounds.size,图像改变
    //      bounds.orign不变,自身坐标系始终不变
    //      bounds.size改变
    //      frame.orign改变,因为bounds.size改变是以UIView中心点为轴变动的,故frame.orign在suerView中的相对位置改变
    //      frame.size改变,因为bounds.size与frame.size是相互影响的,修改一个,另一个会发生改变

    //结论:
    //修改frame.orign,图像移动位置
    //      frame.orign改变
    //      frame.size不变
    //      bounds.orign不变,自身坐标系始终不变
    //      bounds.size不变

    //结论:
    //修改bounds.orign, 图像位置不变
    //      frame.orign不变,因为superView参考坐标系没变
    //      frame.size不变
    //      bounds.orign改变,自身坐标系始终改变
    //      bounds.size不变
    




tips:使用NSStringFromCGRect打印矩阵。


2、属性与成员变量的区别

成员变量使用的是以下定义方法:

@interface ViewController ()
{
    NSString *_name;
}
@end

而属性,则是用@property定义的。

用@property定义属性,为类自动生成了一个下划线的成员变量,同时为成员变量自动生成了setter/getter方法。

不需要使用getter、setter方法访问类数据的时候,可以用成员变量。

属性使用的更加广泛。


3、分类中的属性

分类是对类的拓展,一般只能定义方法。但是也可以定义属性,但是不能为属性生成getter、setter方法

需要手动完成getter、setter方法。例如:

@interface NSObject (Extention)

@property (nonatomic, copy) NSString *name;

@end

@implementation NSObject (Extention)

// 只是告诉编译器,在编译阶段不需要实现setter、getter方法;可以在运行时,创建setter、getter方法
//@dynamic name;

- (void)setName:(NSString *)name{
    
    //第一种方法 保存到临时文件中
    [name writeToFile:FILEPATH atomically:YES encoding:NSUTF8StringEncoding error:NULL];
    
    //第二种方法 运行时方法
    objc_setAssociatedObject(self, @"name", name, 0);
    
}

- (NSString *)name{
    
    //第一种方法 从临时文件中读取
    return [NSString stringWithContentsOfFile:FILEPATH encoding:NSUTF8StringEncoding error:NULL];
    
    //第二种方法 运行时方法
    return objc_getAssociatedObject(self, @"name");
    
}
@end

(因为分类中不会自动生成带下划线的成员变量,因此要另想办法保存数据和读取数据)


4、属性修饰符

/*
 copy 方法:
 类型                 是否产生新的对象    是否可变
 NSString               no              no
 NSMutableString        yes             no
 NSArray                no              no
 NSMutableArray         yes             no
 
 mutableCopy 方法:
 类型                 是否产生新的对象    是否可变
 NSString               yes             yes
 NSMutableString        yes             yes
 NSArray                yes             yes
 NSMutableArray         yes             yes
 
 */


/*
 retain:MRC 对对象使用 引用计数器 +1
 assign:MRC/ARC 对基本数据类型
 weak:ARC 弱指针 解决循环引用 控制器引用UI控件的时候使用
 strong:ARC 强指针
 
 */


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值