I would like to drag one UIView, and have it move the position of other views attached to it as if they were all attached via string. The starting state would be a bunch of UIViews clumped together. If you pull one out, the item it's attached to will begin to move once the minimum distance is met between it and the view being dragged. I was thinking that the best way to accomplish this would be using UIDynamicItemBehavior considering I need it to snap back into place and have weight applied to it. I'm not quite sure how to accomplish this without doing ridiculous code otherwise. The code I do have can be seen below. Unfotunately, I'm having issues with the square item being dragged snapping back to square2. Would anyone have any advice, I'll be happy to clarify if that is needed.
- (void)viewDidLoad
{
[super viewDidLoad];
_containmentView = [[UIView alloc] initWithFrame:CGRectMake(0.0, self.view.frame.size.height/2, self.view.frame.size.width, 200)];
[self.view addSubview:_containmentView];
[_containmentView setBackgroundColor:[UIColor greenColor]];
_square = [[UIView alloc]initWithFrame:CGRectMake(200, 0, 100, 100)];
_square.backgroundColor = [UIColor yellowColor];
[_containmentView addSubview:_square];
_square2 = [[UIView alloc]initWithFrame:CGRectMake(100, 0, 100, 100)];
_square2.backgroundColor = [UIColor redColor];
[_containmentView addSubview:_square2];
_animator = [[UIDynamicAnimator alloc]initWithReferenceView:_containmentView];
_gravity = [[UIGravityBehavior alloc]initWithItems:@[_square, _square2]];
_gravity.gravityDirection = CGVectorMake(-1.0, 0.0);
[_animator addBehavior:_gravity];
_collision = [[UICollisionBehavior alloc]initWithItems:@[_square]];
_collision.collisionDelegate = self;
_collision.translatesReferenceBoundsIntoBoundary = YES; //causes the boundary to use the bounds of the reference view supplied to the UIDynamicAnimator
[_animator addBehavior:_collision];
UIDynamicItemBehavior *itemBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:@[_square]];
itemBehaviour.elasticity = 0.6;
[_animator addBehavior:itemBehaviour];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[_square addGestureRecognizer:gesture];
UIAttachmentBehavior *attach = [[UIAttachmentBehavior alloc] initWithItem:_square2 attachedToItem:_square];
[_animator addBehavior:attach];
}
-(void)handlePan:(UIPanGestureRecognizer *)gesture
{
CGPoint touchPoint = [gesture locationInView:self.view];
UIView* draggedView = gesture.view;
if (gesture.state == UIGestureRecognizerStateBegan) {
// 1. was the pan initiated from the upper part of the recipe?
UIView* draggedView = gesture.view;
CGPoint dragStartLocation = [gesture locationInView:draggedView];
_draggingView = YES;
_previousTouchPoint = touchPoint;
// [_animator updateItemUsingCurrentState:draggedView];
} else if (gesture.state == UIGestureRecognizerStateChanged && _draggingView) {
// 2. handle dragging
float xOffset = _previousTouchPoint.x - touchPoint.x;
gesture.view.center = CGPointMake(draggedView.center.x - xOffset,
draggedView.center.y);
_previousTouchPoint = touchPoint;
// [_animator updateItemUsingCurrentState:draggedView];
} else if (gesture.state == UIGestureRecognizerStateEnded && _draggingView) {
// 3. the gesture has ended
// [self tryDockView:draggedView];
// [self addVelocityToView:draggedView fromGesture:gesture];
[_animator updateItemUsingCurrentState:draggedView];
_draggingView = NO;
}
}