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 bad input," and so on.)
Would it be possible to do this using UIKit Dynamics?
So you'd have to ..
CAKeyframeAnimation * anim =
anim.values = @[
CATransform3DMakeTranslation(-4.0f, 0.0f, 0.0f) ],
CATransform3DMakeTranslation(4.0f, 0.0f, 0.0f) ]
anim.autoreverses = YES;
anim.repeatCount = 1.0f;
anim.duration = 0.1f;
[self.layer addAnimation:anim forKey:nil];
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
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.