IOS学习笔记 运用UIDynamicAnimator仿真引擎来实现物理仿真(1)

景康安
2023-12-01

UIKit DynamicAnimator(UIKit动力学)


UIDynamicAnimator来实现物理仿真,它是苹果内部封装的一个仿真物理引擎

所谓物理仿真就是模拟现实中的物理现象比如:重力、碰撞、弹性等现象


那么怎么实现呢?先查看下源码:

 

UIView的源码中可以看出UIView已经默认实现了动力学元素的协议<UIDynamicItem>那么任何自定义的对象只要实现了该协议就可以仿真物理行为

 

观察下 UIDynamicAnimator 的源码,里面定义了几个重要的方法

    

 1- (instancetype)initWithReferenceView:(UIView*)view;

 2- (void)addBehavior:(UIDynamicBehavior *)behavior;

 3- (void)removeBehavior:(UIDynamicBehavior *)behavior;

 4- (void)removeAllBehaviors;

 

 1、创建一个UIDynamicAnimator对象,参数View定义了物理仿真的范围

 2、增加一个仿真行为参数指定了一个仿真行为类它下面还有其他的子类先查看下:UIDynamicBehavior 它的子类包含仿真行为:

 •    UIAttachmentBehavior      附着行为

 •    UICollisionBehavior       碰撞

 •    UIDynamicItemBehavior     动力学元素行为

 •    UIGravityBehavior         重力

 •    UIPushBehavior            推力

 •    UISnapBehavior            吸附行为

 

 这些行为可以单独使用也可以混着使用来模拟真实的物理行为,也观察下源码:


 如果添加一个重力的行为 UIGravityBehavior那么怎么添加呢看下源码:

 - (instancetype)initWithItems:(NSArray *)items; // 返回一个重力行为的对象

 

 3、删除仿真对象所包含的某一个指定的仿真行为

 4、删除所有的仿真对象的所有仿真行为

 

上面这几个方法就可以实现简单的仿真行为,当然每一个类里面还有其特定的属性


简单的例子:


@interfaceYLViewController ()

{

    UIDynamicAnimator *_animator;

}

@end


@implementation YLViewController


- (void)viewDidLoad

{

    [superviewDidLoad];

    

   UIView *myView = [[UIViewalloc]initWithFrame:CGRectMake(150,30,130,110)];

    myView.backgroundColor = [UIColorlightGrayColor];

    [self.viewaddSubview:myView];

    myView.transform =CGAffineTransformMakeRotation(M_PI_4);//旋转45

    

   UIView *view = [[UIViewalloc]initWithFrame:CGRectMake(140,40,50,50)];

    view.backgroundColor = [UIColorblackColor];

    [self.viewaddSubview:view];

    

    

    // 1、创建仿真对象  参数用于指定仿真的范围

    UIDynamicAnimator *animator = [[UIDynamicAnimatoralloc]initWithReferenceView:self.view];

    

    // 2.创建对象的重力行为  参数用于指定哪个对象的仿真行为

   UIGravityBehavior *gravity = [[UIGravityBehavioralloc]initWithItems:@[myView,view]];

    

    // 2.1为对象再增加一个碰撞行为  参数用于指定哪个对象的仿真行为

    UICollisionBehavior *collision = [[UICollisionBehavioralloc]initWithItems:@[myView,view]];

    

    // 2.1.1 设置碰撞到边界会反弹

    collision.translatesReferenceBoundsIntoBoundary =YES;

    

    // 3.开始仿真仿真对象添加仿真行为

    [animatoraddBehavior:gravity];

    [animatoraddBehavior:collision];

    

    // 4.将局部变量的值赋给全局变量 否则看不到效果

   _animator = animator;  

}



总结下:代码很简单但是设计明显不合理,没有遵循 MVC 设计模式

 类似资料: