ios动画专题iOS学习开发iOS Developer

浅谈 iOS UI 动画

2016-06-23  本文已影响456人  _凉风_

一、定时任务

// 1.5s后自动调用self的hideHUD方法
[self performSelector:@selector(hideHUD) withObject:nil afterDelay:1.5];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 1.5s后自动执行这个block里面的代码
    self.hud.alpha = 0.0;
});
// 1.5s后自动调用self的hideHUD方法
[NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(hideHUD) userInfo:nil repeats:NO];
// repeats如果为YES,意味着每隔1.5s都会调用一次self的hidHUD方法

NSTimer「定时器」
作用:

使用:

// 开启一个定时器任务
// 每隔 ti 秒,调用 1次 aTarget 的 aSelector方法,yesOrNo 是否重复调用 aSelector方法
+(NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInerval)ti target:(id)aTarget selector:(SEL)aSelector userInfor:(id)userInfor repeats:(BOOL)yesOrNo;

// 停止定时器工作
// 一旦定时器停止,不能再次执行任务
// 只能创建新的定时器,执行新任务
- (void)invalidate;
[self.timer invalidate];
self.timer = nil;

// 解决定时器在主线不工作问题
NSTimer *timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(functionName) userInfor:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

二、Quartz 2D

简介

作用

1. 图形上下文「Graphics Context」

简介

作用

种类

2. 自定义 View 的具体步骤

  1. 新建一个类,继承自 UIView
  2. 实现 - (void)drawRect:(CGRect)rect 方法
    然后在这个方法中
    • 取得跟当前view相关联的图形上下文
    • 绘制相应的图形内容
    • 利用 图形上下文 将绘制的所有内容渲染显示到 view 上面

具体操作

- (void)drawRect:(CGRect)rect {
    // 0. 获取上下文 CGContextRef 是结构体,这里面已表明是指针,所以是ctx而非*ctx
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 1. 描述路径
    //    设置 起点
    CGContextMoveToPoint(ctx, 50, 50);
    //    设置 下一个点的位置,并和上一个点连线
    CGContextAddLineToPoint(ctx, 200, 200);
    // 2. 渲染上下文,stroke 空心的形式显示「圆圈、线段都属于空心」
    CGContextStrokePath(ctx);
}

3. drawRect 方法

作用

何时 drawRect 被调用

4. 图形上下文栈

简介:将当前的上下文copy一份,保存到栈顶「那个栈叫做图形上下文栈
作用

代码示例


- (void)drawRect:(CGRect)rect
{
    // 获得上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 1. 将ctx拷贝一份放到栈中
    CGContextSaveGState(ctx);
    
    // 设置绘图状态
    CGContextSetLineWidth(ctx, 10);
    [[UIColor redColor] set];
    CGContextSetLineCap(ctx, kCGLineCapRound);
    
    // 第1根线
    CGContextMoveToPoint(ctx, 50, 50);
    CGContextAddLineToPoint(ctx, 120, 190);
    // 将绘制的图形渲染到上下文中
    CGContextStrokePath(ctx);
    
    // 2. 将栈顶的上下文出栈,替换当前的上下文
    CGContextRestoreGState(ctx);
    
    // 第2根线
    CGContextMoveToPoint(ctx, 10, 70);
    CGContextAddLineToPoint(ctx, 220, 290);
    CGContextStrokePath(ctx);
    // 以下代码和 CGContextStrokePath 效果一样,但更加通用
    CGContextDrawPath(ctx, kCGPathStroke);
}

三、图层动画

1. CALayer

简介

作用

属性

// 边框宽度
@property CGFloat borderWidth;
// 圆角半径
@property CGFloat cornerRadius;

// 宽度和高度
@property CGRect bounds;

// 位置:坐标系是 父layer的坐标系,决定了本类中 anchorPoint点的位置在父layer坐标系的位置
@property CGPoint position;
// 锚点: 坐标系是layer自己的坐标系,决定了layer绕哪个点旋转「x,y的范围都是 0 ~ 1」
@property CGPoint anchorPoint;

// 边框颜色「CGColorRef类型」
@property CGColorRef borderColor;
// 内容「比如设置为图片CGImageRef」
@property(retain) id contents;
// 背景颜色「CGColorRef类型」
@property CGColorRef backgroundColor;

// 形变属性
@property CATransform3D transform;

方法

// CATransform3DMakeRotation(旋转角度, x, y, z)
// 旋转的轴心是 原点到传入的点(x, y, z) 的连线
self.iconView.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);

// 可以传递哪些key path, 在官方文档搜索 "CATransform3D key paths"
[self.iconView.layer setValue:@(-100) forKeyPath:@"transform.translation.x"];

2. CALayer 中的数据类型转换

框架的归属不同

框架的使用范围不同

为了保证可移植性

/**
 *  CG:Core Graphics框架
 *  CA:Core Animation框架
 *  Ref:引用
 *  转换:UIKit 框架转换为 CG框架的东西,直接 .CG** 就可以
 
 *  图片一共三层
 *  1. 本类的层,用来接收触摸手势
 *  2. UIImageView 绘制层
 *  3. UIImage 变化层
 */

// 新建图层
//    方法1:[[CALayer alloc] init];
//    方法2:[CALayer layer];
CALayer *layer = [CALayer layer];

// UIKit 框架转换为 CG框架的 CGColor
layer.backgroundColor = [UIColor redColor].CGColor;
layer.bounds = CGRectMake(0, 0, 100, 100);
layer.position = CGPointMake(200, 100);
layer.cornerRadius = 10;
// 将画的形状剪裁掉
layer.masksToBounds = YES;

// UIKit 框架转换为 CG框架的 CGImage
// contents 的属性类型是 id,所以这里要进行强行转换
layer.contents = (id)[UIImage imageNamed:@"catImgName"].CGImage;
[self.view.layer addSublayer:layer];

3. UIView 和 CALayer 的比较

性能比较

结构比较

4. 非 Root Layer 的隐式动画

每一个 UIView 内部都默认关联着一个 CALayer,这个 Layer 称为 Root Layer(根层)
所有的非 Root Layer,也就是手动创建的 CALayer 对象,都存在着 隐式动画

简介

常见的 Animatable Properties「可动画属性」列举

通过动画事务开关隐式动画

// 开启 动画事务
[CATransaction begin];
// 隐式动画效果关闭
[CATransaction setDisableActions:YES];
self.testView.layer.position = CGPointMake(10, 10); // 没有隐式动画效果了
// 关闭 动画事务
[CATransaction commit];

5. 自定义 Layer

I. 创建 CALayer 子类

步骤

注意

MyLayer *layer = [MyLayer layer];
// 设置层的宽高
layer.bounds = CGRectMake(0, 0, 100, 100);
// 设置层的位置
layer.position = CGPointMake(100, 100);
// 开始绘制图层
[layer setNeedsDisplay];
// 添加子层
[self.view.layer addSublayer:layer];

II. 设置 CALayer 代理

步骤

注意

// 创建图层
CALayer *layer = [CALayer layer];

// 设置 delegate,self 指控制器
// 这里的 delegate 不需要遵守协议,因为这里的代理方法drawLayer:inContext:是 NSObject 对象都有的方法
layer.delegate = self;

// 设置层的宽高
layer.bounds = CGRectMake(0, 0, 100, 100);
// 设置层的位置
layer.position = CGPointMake(100, 100);

// 开始绘制图层
// 调用这个方法,才会通知 delegate 进行绘图
[layer setNeedsDisplay];

[self.view.layer addSublayer:layer];

6. UIView 的详细显示过程

  1. view 内部的 Layer 会准备好一个 CGContextRef「图层类型上下文」

  2. 调用 delegate「这里就是 UIView」的 drawLayer:inContext: 方法
    传入已经准备好的 CGContextRef 对象

  3. view 在 drawLayer:inContext: 方法中又会调用自己的 drawRect: 方法

  4. view 就可以在 drawRect: 方法中实现绘图代码, 所有东西最终都绘制到 view.layer 上面

  5. 系统再将 view.layer 的内容拷贝到屏幕, 于是完成了 view 的显示

CGContextRef 对象是当前的上下文

由 layer 传入的 CGContextRef 对象

四、核心动画

Core Animation 框架简介

使用步骤

  1. 初始化一个 CAAnimation 对象,并设置一些动画相关属性
  2. 通过调用 CALayer 的 addAnimation:forKey: 方法增加 CAAnimation 对象到 CALayer 中,这样就能开始执行动画了
  3. 通过调用 CALayer 的 removeAnimationForKey: 方法可以停止 CALayer 中的动画

1. CAAnimation 抽象类

想执行动画,就必须初始化一个 CAAnimation 对象

I. CAMediaTiming 协议属性

fillMode 属性值
要想 fillMode 有效,最好设置 removedOnCompletion = NO

父图层 和 图层本地的时间 换算公式

CALayer 上动画的暂停和恢复

// 暂停 CALayer 的动画
- (void)pauseLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0; // 让CALayer的时间停止走动
    layer.timeOffset = pausedTime; // 让CALayer的时间停留在pausedTime这个时刻
}

// 恢复 CALayer 的动画
- (void)resumeLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = layer.timeOffset;
    layer.speed = 1.0;      // 让CALayer的时间继续行走
    layer.timeOffset = 0.0; // 取消上次记录的停留时刻
    layer.beginTime = 0.0;  // 取消上次设置的时间
    
    // 计算暂停的时间「用 CACurrentMediaTime() - pausedTime 也一样」
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    // 设置相对于父坐标系的开始时间「往后退timeSincePause」
    layer.beginTime = timeSincePause;
}

II. CAAnimation 本身的属性

timingFunction 可选的值有:

kCAMediaTimingFunctionLinear  //「线性」:匀速,给你一个相对静态的感觉
kCAMediaTimingFunctionEaseIn  //「渐进」:动画缓慢进入,然后加速离开
kCAMediaTimingFunctionEaseOut //「渐出」:动画全速进入,然后减速的到达目的地
kCAMediaTimingFunctionEaseInEaseOut //「渐进渐出」:动画缓慢的进入,中间加速,然后减速的到达目的地「默认」

代理需要实现的方法有:

// 动画开始执行的时候触发这个方法
- (void)animationDidStart:(CAAnimation *)anim;
// 动画执行完毕的时候触发这个方法
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

注意:以上所有属性和方法都属于 CAAnimation 抽象类,所以它的子类都能使用

2. CAPropertyAnimation 抽象类「继承自 CAAnimation」

简介

3. CABasicAnimation 类「继承自 CAPropertyAnimation」

简介

示例:平移动画


// 1. 说明这个动画对象要对 CALayer的position属性 执行动画
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];

//    fromValue 到 toValue 的动画持续 1.5s
anim.duration = 1.5; 
//    position属性值从(50, 80)渐变到(300, 350)
//    fromValue 默认是当前的值
anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, 80)];
//    toValue:达到多少值
//    byValue:增加多少值
anim.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 350)];

//    设置动画的代理「self指控制器」
anim.delegate = self;

// 2. 让图层保持动画执行后的状态「这里以下两行代码虽然这么保持了状态,但实质上图层的属性值没有改变」
//    动画执行完毕后不删除动画
anim.removedOnCompletion = NO; // 默认是 YES
//    保持最新的状态

anim.fillMode = kCAFillModeForwards;

// 3. 添加动画对象到图层上
[_myView.layer addAnimation:anim forKey:@"translate"];
// 1. 说明 动画执行对象属性
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.duration = 1;

// 2. 设置 3D 图形运动
CATransform3D form = CATransform3DMakeTranslation(350, 350, 0);
anim.toValue = [NSValue valueWithCATransform3D:form];

// 3. 添加动画对象到图层上
[_myView.layer addAnimation:anim forKey:nil];

4. CAKeyframeAnimation 类「继承自 CAPropertyAnimation」

简介

属性解析

重要属性:calculationMode「计算模式」

CalculationMode 目前提供如下几种模式:

示例代码

// 1. 创建帧动画
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];

anim.keyPath = @"position";
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
anim.duration = 2.0;

// 2. 设置图层移动路径
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(100, 100, 200, 200));
anim.path = path;
CGPathRelease(path);

// 3. 设置动画的执行节奏
//    kCAMediaTimingFunctionEaseInEaseOut : 一开始比较慢, 中间会加速,  临近结束的时候, 会变慢
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

// 代理不需要遵守任何协议「因为这些协议是任何对象都遵守的」
// 可以执行的协议方法:
//    - (void)animationDidStart:(CAAnimation *)anim 动画开始时执行
//    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 动画结束时执行
anim.delegate = self;

// 4. 添加动画
[self.redView.layer addAnimation:anim forKey:nil];

CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
anim.keyPath = @"transform.rotation";

anim.values = @[@(Angle2Radian(-5)),  @(Angle2Radian(5)), @(Angle2Radian(-5))];
anim.duration = 0.25;
// 动画的重复执行次数
anim.repeatCount = MAXFLOAT;

// 保持动画执行完毕后的状态
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;

// 给 UI 控件的图层添加动画,图层动,UI 控件跟着动「因为控件的显示靠图层」
// shake 是和 动画对象绑定的键值对的 key 值
[self.iconView.layer addAnimation:anim forKey:@"shake"];

// 通过 key 值 shake 删除动画对象
[self.iconView.layer removeAnimationForKey:@"shake"];

5. CATransition 类「继承自 CAAnimation」

简介

属性解析

fade     // 交叉淡化过渡 kCATransitionFade 「不支持过渡方向」
push     // 新视图把旧视图推出去 kCATransitionPush
moveIn   // 新视图移到旧视图上面 kCATransitionMoveIn
reveal   // 将旧视图移开,显示下面的新视图 kCATransitionReveal
cube     // 立方体翻滚效果
oglFlip  // 上下左右翻转效果
suckEffect   // 收缩效果,如一块布被抽走「不支持过渡方向」
rippleEffect // 滴水效果「不支持过渡方向」
pageCurl     // 向上翻页效果
pageUnCurl   // 向下翻页效果
cameraIrisHollowOpen  // 相机镜头打开效果「不支持过渡方向」
cameraIrisHollowClose // 相机镜头关上效果「不支持过渡方向」
kCATransitionFromRight // 从右 → 左

kCATransitionFromLeft // 从左 → 右

kCATransitionFromBottom  // 从下 → 上

kCATransitionFromTop // 从下 → 下

示例代码

// 创建转场动画对象
CATransition *anim = [CATransition animation];
    
anim.type = @"pageCurl"; // 转场类型
anim.subtype = kCATransitionFromRight; // 转场方向
anim.duration = 0.5;
anim.startProgress = 0.0;
anim.endProgress = 0.5;

[self.view.layer addAnimation:anim forKey:nil];

6. CAAnimationGroup 类「继承自 CAAnimation」

简介

属性解析

// 1.创建旋转动画对象
CABasicAnimation *rotate = [CABasicAnimation animation];
rotate.keyPath = @"transform.rotation";
rotate.toValue = @(M_PI);

// 2.创建缩放动画对象
CABasicAnimation *scale = [CABasicAnimation animation];
scale.keyPath = @"transform.scale";
scale.toValue = @(0.0);

// 3.平移动画
CABasicAnimation *move = [CABasicAnimation animation];
move.keyPath = @"transform.translation";
move.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];

// 4.将所有的动画添加到动画组中
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[rotate, scale, move];
group.duration = 2.0;
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;

[self.myvie.layer addAnimation:group forKey:nil];

7. UIView 动画

简介

示例代码

[UIView beginAnimations:nil context:nil];

// 添加修改的属性「产生动画」
self.myview.center = CGPointMake(200, 300);

// 动画执行完毕后, 会自动调用self的animateStop方法
//    [UIView setAnimationDelegate:self];
//    [UIView setAnimationDidStopSelector:@selector(animateStop)];
[UIView commitAnimations];

I. UIView 的常用方法

// 设置动画代理对象,当动画**开始**或者**结束**时会发消息给代理对象
+ (void)setAnimationDelegate:(id)delegate;

// 当动画即将开始时,执行代理对象的selector,并且把beginAnimations:context:中传入的参数传进selector
+ (void)setAnimationWillStartSelector:(SEL)selector;

// 当动画结束时,执行代理对象的selector,并且把beginAnimations:context:中传入的参数传进selector
+ (void)setAnimationDidStopSelector:(SEL)selector;

+ (void)setAnimationDuration:(NSTimeInterval)duration; // 动画的持续时间,秒为单位
+ (void)setAnimationDelay:(NSTimeInterval)delay; // 动画延迟delay秒后再开始
+ (void)setAnimationStartDate:(NSDate *)startDate; // 动画的开始时间,默认为now
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve; // 动画的节奏控制,具体看下面的”备注”
+ (void)setAnimationRepeatCount:(float)repeatCount; // 动画的重复次数

// 如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses; 

// 设置视图view的过渡效果,transition指定过渡类型,cache设置YES代表使用视图缓存,性能较好
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache

II. UIView 的 Block 动画

// 方法 1
+ (void)animateWithDuration:(NSTimeInterval)duration             // 动画的持续时间
                      delay:(NSTimeInterval)delay                // 动画延迟delay秒后开始
                    options:(UIViewAnimationOptions)options      // 动画的节奏控制
                 animations:(void (^)(void))animations           // 将改变视图属性的代码放在这个block中
                 completion:(void (^)(BOOL finished))completion; // 动画结束后,自动调用这个block

// 方法 2
+ (void)transitionWithView:(UIView *)view                       // 动画的持续时间
                  duration:(NSTimeInterval)duration             // 需要进行转场动画的视图
                   options:(UIViewAnimationOptions)options      // 转场动画的类型
                animations:(void (^)(void))animations           // 将改变视图属性的代码放在这个block中
                completion:(void (^)(BOOL finished))completion; // 动画结束后,自动调用这个block

// 方法 3 UIView 的转场动画
+ (void)transitionFromView:(UIView *)fromView                   // 要移除的视图
                    toView:(UIView *)toView                     // 要添加的视图
                  duration:(NSTimeInterval)duration             // 动画的持续时间
                   options:(UIViewAnimationOptions)options      // 转场动画的类型
                completion:(void (^)(BOOL finished))completion; // 动画结束后,自动调用这个block

// 方法 3 调用完毕后,相当于执行了下面两句代码
//   添加toView到父视图
[fromView.superview addSubview:toView];
//   把fromView从父视图中移除
[fromView.superview removeFromSuperview];

8. UIImageView 的帧动画

简介

属性解析

方法解析

9. UIActivityIndicatorView

简介

方法解析

UIActivityIndicatorViewStyle 有 3 个值可供选择:

五、物理引擎

1. UIDynamic

简介

使用步骤

  1. 创建 物理仿真器「设置仿真范围」

物理仿真器「Dynamic Animator」
让物理仿真元素执行具体的物理仿真行为

  1. 创建 物理仿真行为「在添加 物理仿真元素

物理仿真元素「Dynamic Item」
谁要进行物理仿真?

  1. 物理仿真行为 添加到 物理仿真器

**物理仿真行为「Dynamic Behavior」 **
执行怎样的物理仿真效果?怎样的动画效果?

代码示例

// 1. 创建仿真器,实际使用中用懒加载的方法「这里的仿真器 必须是不易被销毁的属性」
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
// 2. 创建物理仿真行为「这里用重力行为来代表」
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.controlView]];
// 3. 添加 物理仿真行为
[self.animator addBehavior:gravity];

2. 三大元素

I. 物理仿真元素「Dynamic Item」

制作仿真元素

已经是仿真元素的控件

II. 物理仿真行为「Dynamic Behavior」

特点

UIDynamic 提供的物理仿真行为


UIGravityBehavior     // 重力行为:给定重力方向、加速度,让物体朝着重力方向掉落
UICollisionBehavior   // 碰撞行为:通过添加边界「boundary」让物理碰撞局限在某个空间中,实现碰撞效果
UISnapBehavior        // 捕捉行为:让物体迅速冲到某个位置「捕捉位置」捕捉到位置之后会带有一定的震动
UIPushBehavior        // 推动行为
UIAttachmentBehavior  // 附着行为
UIDynamicItemBehavior // 动力元素行为

重力行为


// 添加到重力行为中的所有物理仿真元素
@property (nonatomic, readonly, copy) NSArray* items;

// 重力方向(是一个二维向量)
@property (readwrite, nonatomic) CGVector gravityDirection;

// 重力方向(是一个角度,以x轴正方向为0°,顺时针正数,逆时针负数)
@property (readwrite, nonatomic) CGFloat angle;

// 位移 = 初速度 * 时间 + (1/2)* 加速度 * 时间²
// 量级(用来控制加速度,1.0代表加速度是1000 points/second²)
@property (readwrite, nonatomic) CGFloat magnitude;

// 初始化
// item参数 :里面存放着物理仿真元素
- (instancetype)initWithItems:(NSArray *)items;
// 添加1个物理仿真元素
- (void)addItem:(id <UIDynamicItem>)item;
// 移除1个物理仿真元素
- (void)removeItem:(id <UIDynamicItem>)item;

碰撞行为

// 是否以参照视图的bounds为边界
@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;
// 设置参照视图的bounds为边界,并且设置内边距
- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;

// 碰撞模式(分为3种,元素碰撞、边界碰撞、全体碰撞)
@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

// 代理对象(可以监听元素的碰撞过程)
@property (nonatomic, assign, readwrite) id <UICollisionBehaviorDelegate> collisionDelegate;

- (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier;

@property (nonatomic, readonly, copy) NSArray* boundaryIdentifiers;
- (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier;

- (void)removeAllBoundaries;

// 添加一条看不见的路径「自己绘制」作为边框「或在固定图形中碰撞」

- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath;

// 添加一条看不见的线「由两个点确定」作为边框
- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;

捕捉行为


// 用于减幅、减震(取值范围是0.0 ~ 1.0,值越大,震动幅度越小)
@property (nonatomic, assign) CGFloat damping;

// 初始化
- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;

III. 物理仿真器「Dynamic Animator」

简介

常见属性

// 参照视图:通过这个视图来确定 仿真范围
@property (nonatomic, readonly) UIView* referenceView;
// 添加到物理仿真器中的所有物理仿真行为
@property (nonatomic, readonly, copy) NSArray* behaviors;
// 是否正在进行物理仿真
@property (nonatomic, readonly, getter = isRunning) BOOL running;
// 代理对象「能监听物理仿真器的仿真过程,比如开始和结束」
@property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate;

常见方法

// UIDynamicAnimator 的初始化
// view参数:是一个参照视图,表示物理仿真的范围
- (instancetype)initWithReferenceView:(UIView *)view;

// 添加1个物理仿真行为
- (void)addBehavior:(UIDynamicBehavior *)behavior;

// 移除1个物理仿真行为
- (void)removeBehavior:(UIDynamicBehavior *)behavior;

// 移除之前添加过的所有物理仿真行为
- (void)removeAllBehaviors;
上一篇下一篇

猜你喜欢

热点阅读