·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> app软件开发 >> IOS开发 >> IOS-UI-UIDynamic(一)

IOS-UI-UIDynamic(一)

作者:佚名      IOS开发编辑:admin      更新时间:2022-07-23

UIDynamic是从iOS7开始引入的技术 属于UIkit框架 可以模拟显示生活中的物理现象 如碰撞 抖动 摆动等

 一.

使用UIDynamic步骤:

1.创建一个动力效果器UIDynamicAnimator

2.创建动力效果(Behavior)添加到对于的视图上

3.将动力效果添加到动力效果器中

 注:必须遵守了UIDynamicItem这个协议才可以使用动力效果,UIView默认已经遵守了UIDynamicItem协议

 玩动力效果  如玩电吉他   电吉他有效果器  可以添加各种电子效果

 动力效果  也有一个效果器 叫做 动力效果器  里面可以添加 动力效果

 电吉他切换效果  会把上一个效果移除

 动力效果 也是一样

 电吉他可以叠加多个效果

 动力效果 也是一样

 UIDynamic提供的动力效果

二.

 UIGravityBehavior:重力效果(设置重力的方向 加速度 让物体(视图)朝着重力方向掉落)

重力效果的属性:

 NSArray *items;添加到重力效果中的所有效果作用对象

CGVector gravityDirection;重力方向(是一个二维向量)以左上角为坐标原点 x 负数向左 正数向右  y 负数向上  正数向下  数字越大  重力效果越大

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

  CGFloat magnitude;量级(用来控制加速度,1.0代表加速度是1000 points /second²)重力加速度越大 碰撞越厉害

UICollisionBehavior:碰撞效果()可以让物体之间实现碰撞效果, 也可以通过添加边界(boundary)在边界实现碰撞效果

 边界相关的方法:

 - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath; 添加一个贝塞尔曲线路径的边界

 - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2; 通过添加两个点连成的线 作为边界

 - (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier; 通过ID找到边界路径

 - (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier; 移除ID对应的边界

 @PRoperty (nonatomic, readonly, copy) NSArray* boundaryIdentifiers; 边界数组

 - (void)removeAllBoundaries;移除所有边界

 typedef NS_OPTIONS(NSUInteger, UICollisionBehaviorMode) {

 UICollisionBehaviorModeItems        = 1 << 0,元素碰撞

 UICollisionBehaviorModeBoundaries   = 1 << 1,边界碰撞

 UICollisionBehaviorModeEverything   = NSUIntegerMax 全体碰撞

 } NS_ENUM_AVAILABLE_IOS(7_0);

碰撞效果的代理方法: 

 //两个元素相互碰撞

 - (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;

 - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;

 // 视图碰撞边界的时候 触发

 - (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p;

 - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier;

三.具体代码 

@interface ViewController ()<UIDynamicAnimatorDelegate,UICollisionBehaviorDelegate>
{
    UIDynamicAnimator * dynamicAnimator;
    UIView * view1;
      UIView * view2;
     UIView * view3;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
//    动力效果器
    dynamicAnimator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
//    self.view 产生动力效果的区域
    dynamicAnimator.delegate = self;
    view1 =[[UIView alloc]initWithFrame:CGRectMake(0,0,90 , 90)];
    view1.center = self.view.center;
    view1.backgroundColor = [UIColor redColor];
    
    [self.view addSubview:view1];
    view2 =[[UIView alloc]initWithFrame:CGRectMake(0,0,90 , 90)];
    view2.center = CGPointMake(self.view.center.x+100, self.view.center.y+100);
    view2.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:view2];
    view3 =[[UIView alloc]initWithFrame:CGRectMake(0,0,90 , 90)];
  
    view3.backgroundColor = [UIColor blueColor];
    [self.view addSubview:view3];


   }
#pragma mark -------手指触摸屏幕 添加动力效果--------------------------
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch * touch = [touches anyObject];
    CGPoint touchpoint = [touch locationInView:self.view];
    view1.center = touchpoint;
    view2.center = CGPointMake(self.view.center.x+100, self.view.center.y+100);
      view3.center = CGPointMake(self.view.center.x+10, self.view.center.y+10);
    view1.hidden = NO;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//    把之前的动力效果移除
    [dynamicAnimator removeAllBehaviors];
//在View1上添加重力效果
    UIGravityBehavior * gravity = [[UIGravityBehavior alloc]initWithItems:@[view1]];
//    设置加速度
    gravity.magnitude = 100;
//设置动力效果的方向
    gravity.gravityDirection = CGVectorMake(0, 1);
//    添加到效果器 开始动力效果
    [dynamicAnimator addBehavior:gravity];
    UICollisionBehavior * collision = [[UICollisionBehavior alloc]initWithItems:@[view1,view2,view3]];
    collision.collisionDelegate = self;
    collision.translatesReferenceBoundsIntoBoundary = YES;
//    如果设置了 两个元素之间相互碰撞 设置了边界 也就不起作用了
//    collision.collisionMode = UICollisionBehaviorModeItems;
    [dynamicAnimator addBehavior:collision];
#pragma mark----------------动力元素效果----------------------------
//可以与其他的 动力效果 配合使用
    UIDynamicItemBehavior * item = [[UIDynamicItemBehavior alloc]initWithItems:@[view2,view1,view3]];
//    设置元素的跳跃度
    item.elasticity = 0.9;
    [dynamicAnimator addBehavior:item];
    
}

当然还可以设置边界,当只添加View1时

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//    把之前的动力效果移除
    [dynamicAnimator removeAllBehaviors];
//在View1上添加重力效果
    UIGravityBehavior * gravity = [[UIGravityBehavior alloc]initWithItems:@[view1]];
//    设置加速度
    gravity.magnitude = 100;
//设置动力效果的方向
    gravity.gravityDirection = CGVectorMake(0, 1);
//    添加到效果器 开始动力效果
    [dynamicAnimator addBehavior:gravity];
#pragma mark ------碰撞效果-----------------------
    UICollisionBehavior * collision = [[UICollisionBehavior alloc]initWithItems:@[view1,view2]];
    collision.collisionDelegate = self;
//    设置一条下斜线边界
//    [collision addBoundaryWithIdentifier:@"line1" fromPoint:CGPointMake(0, 300) toPoint:CGPointMake(400, 600)];
//设置竖直线边界
//    [collision addBoundaryWithIdentifier:@"line2" fromPoint:CGPointMake(300, 0) toPoint:CGPointMake(300, 600)];
//    通过贝瑟尔曲线 画一个圆
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 200, 300, 300)];
    [collision addBoundaryWithIdentifier:@"yuan" forPath:path];
    
    
//把动力效果器的范围当做边界
    collision.translatesReferenceBoundsIntoBoundary = YES;
    [dynamicAnimator addBehavior:collision];
}