@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];