UIDynamicAnimator
// Do any additional setup after loading the view, typically from a nib.
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 80, 100, 100)];
view.backgroundColor = [UIColor blueColor];
[self.view addSubview:view];
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0, 250, 150, 20)];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
UIDynamicAnimator *_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems: @[view]];
[_animator addBehavior:gravityBehavior];
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[view]];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
[_animator addBehavior:collisionBehavior];
CGPoint toPoint = CGPointMake(redView.frame.origin.x + redView.frame.size.width, redView.frame.origin.y + redView.frame.size.height);
[collisionBehavior addBoundaryWithIdentifier:@"barrier" fromPoint:redView.frame.origin toPoint:toPoint];
//
UIView *pointView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[pointView setBackgroundColor:[UIColor yellowColor]];
[self.view addSubview:pointView];
UIDynamicItemBehavior *item = [[UIDynamicItemBehavior alloc] initWithItems:@[view]];
item.elasticity = 0.5;
[_animator addBehavior:item];
collisionBehavior.action = ^{
[pointView setCenter:view.center];
[pointView setTransform:view.transform];
};
}
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p
{
NSLog(@"%@ %@", identifier, item);
// 发生碰撞的时候,做点什么?
UIView *view = (UIView *)item;
// 提出条件:只有跟红色的障碍物碰撞才会改变颜色
NSString *ID = [NSString stringWithFormat:@"%@", identifier];
if ([ID isEqualToString:@"barrier"]) {
// 碰撞时,改变颜色
[view setBackgroundColor:[UIColor greenColor]];
[UIView animateWithDuration:0.3f animations:^{
// 碰撞后,恢复颜色
[view setBackgroundColor:[UIColor blueColor]];
}];
}
}
{
UIDynamicAnimator *_animator;
UIAttachmentBehavior *_attachment;
// 大虫子头部视图
UIView *_headerView;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 1. 实例化animator
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
// 2. 绘制所有的视图
CGFloat startX = 20;
CGFloat startY = 60;
CGFloat r = 12;
NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:9];
for (NSInteger i = 0; i < 9; i++) {
UIView *view = nil;
if (i < 8) {
view = [[UIView alloc] initWithFrame:CGRectMake(startX + i * 2 * r, startY, 2 * r, 2 * r)];
[view.layer setCornerRadius:r];
view.backgroundColor = [UIColor blueColor];
} else {
view = [[UIView alloc] initWithFrame:CGRectMake(startX + i * 2 * r, startY - r, 4 * r, 4 * r)];
[view.layer setCornerRadius:2 * r];
view.backgroundColor = [UIColor greenColor];
}
[self.view addSubview:view];
[arrayM addObject:view];
}
_headerView = arrayM[8];
// 3. 附加行为
for (NSInteger i = 0; i < 8; i++) {
UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:arrayM[i] attachedToItem:arrayM[i + 1]];
[_animator addBehavior:attachment];
}
// 4. 重力行为
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:arrayM];
[_animator addBehavior:gravity];
// 5. 碰撞行为
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:arrayM];
collision.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:collision];
// 6. 添加手势监听
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
[self.view addGestureRecognizer:pan];
}
#pragma mark - 手势拖动监听方法
- (void)panGesture:(UIPanGestureRecognizer *)sender
{
CGPoint location = [sender locationInView:self.view];
// 拖动头部
if (UIGestureRecognizerStateBegan == sender.state) {
// 1. 定义一个附加行为
_attachment = [[UIAttachmentBehavior alloc] initWithItem:_headerView attachedToAnchor:location];
[_animator addBehavior:_attachment];
} else if (UIGestureRecognizerStateChanged == sender.state) {
[_attachment setAnchorPoint:location];
} else if (UIGestureRecognizerStateEnded == sender.state) {
[_animator removeBehavior:_attachment];
}
}