There are many situations where you need to \"shake\" a UIView.
(For example, \"draw child user\'s attention to a control\", \"connection is slow\", \"user enters ba
If you want to use UIKit Dynamics, you can:
First, define a governing animator:
@property (nonatomic, strong) UIDynamicAnimator *animator;
And instantiate it:
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
Second, add attachment behavior to that animator for view in current location. This will make it spring back when the push is done. You'll have to play around with damping
and frequency
values.
UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:viewToShake attachedToAnchor:viewToShake.center];
attachment.damping = 0.5;
attachment.frequency = 5.0;
[self.animator addBehavior:attachment];
These values aren't quite right, but perhaps it's a starting point in your experimentation.
Apply push behavior (UIPushBehaviorModeInstantaneous
) to perturb it. The attachment behavior will then result in its springing back.
UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:@[viewToShake] mode:UIPushBehaviorModeInstantaneous];
push.pushDirection = CGVectorMake(100, 0);
[self.animator addBehavior:push];
Personally, I'm not crazy about this particular animation (the damped curve doesn't feel quite right to me). I'd be inclined use block based animation to move it one direction (with UIViewAnimationOptionCurveEaseOut
), upon completion initiate another to move it in the opposite direction (with UIViewAnimationOptionCurveEaseInOut
), and then upon completion of that, use the usingSpringWithDamping
rendition of animateWithDuration
to move it back to its original spot. IMHO, that yields a curve that feels more like "shake if wrong" experience.