@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segment;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (nonatomic, strong) UIDynamicAnimator *animator;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.redView.transform = CGAffineTransformMakeRotation(M_PI_4);
}
- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event {
// [self testGravity];
// [self testGravityAndCollision];
// [self testGravityAndCollision2];
// [self testGravityAndCollision3];
[self testSnap:touches];
}
- (void)testGravity {
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
[gravity addItem:self.redView];
[self.animator addBehavior:gravity];
}
- (void)testGravityAndCollision {
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
gravity.gravityDirection = CGVectorMake(0, 1); // 二维向量,表示方向。另一个确定方向还有 angle 属性
gravity.magnitude = 1; // 重力加速度。加速度越大,碰撞越厉害
[gravity addItem:self.redView];
UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
collision.translatesReferenceBoundsIntoBoundary = YES;
[collision addItem:self.redView];
[collision addItem:self.progressView];
[collision addItem:self.segment];
[self.animator addBehavior:gravity];
[self.animator addBehavior:collision];
}
- (void)testGravityAndCollision2 {
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
[gravity addItem:self.redView];
[self.animator addBehavior:gravity];
UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
[collision addBoundaryWithIdentifier:@"line1" fromPoint:CGPointMake(0, 160) toPoint:CGPointMake(320, 400)];
[collision addBoundaryWithIdentifier:@"line2" fromPoint:CGPointMake(320, 0) toPoint:CGPointMake(320, 400)];
[collision addItem:self.redView];
[self.animator addBehavior:collision];
}
- (void)testGravityAndCollision3 {
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
[gravity addItem:self.redView];
[self.animator addBehavior:gravity];
UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
[collision addBoundaryWithIdentifier:@"circle" forPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 320, 320)]];
[collision addItem:self.redView];
[self.animator addBehavior:collision];
}
- (void) testSnap:(NSSet
*)touches {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:touch.view];
UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.redView snapToPoint:point];
snap.damping = arc4random_uniform(10) / 10.0;
[self.animator removeAllBehaviors];
[self.animator addBehavior:snap];
}
- (UIDynamicAnimator *)animator {
if (_animator == nil) {
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
}
return _animator;
}
@end
物理仿真元素:遵循UIDynamicItem协议的对象;
物理仿真行为:继承UIDynamicBehavior,UIDynamic提供了
UIGravityBehavior-重力行为
UICollisionBehavior-碰撞行为
UISnapBehavior-捕捉行为
UIPushBehavior-推动行为
UIAttachmentBehavior-附着行为
UIDynamicItemBehavior-动力元素行为
物理仿真器:让物理仿真元素执行具体的物理仿真行为,它是UIDynamicAnimator类型的对象;
步骤:
创建物理仿真器,设置仿真范围;
创建物理仿真行为,添加物理仿真元素;
将物理仿真行为添加到物理仿真器中,开始仿真;
注意:
如果要进行连续的捕捉行为,需要先把前面的捕捉行为从物理仿真器中移除;
[self.animator removeAllBehaviors];
[self.animator addBehavior:snap];