Shake UIView ... but using UIKit Dynamics

There are many situations where you need to “shake” a UIView.

(For example, “draw the attention of the child user to the control”, “connection is slow”, “user enters invalid input”, etc.)

Can this be done using UIKit Dynamics?

So you have to ...

  • take a representation of say at 0,0

  • add spring concept

  • give it a push, say "left"

  • it should lean back and forth on spring, eventually settling down again at 0.0

Is it possible? I could not find an example in Apple demos. Greetings

Note that, as Niels explains below, spring is not necessarily the “physical sensation” you want for some of these situations: in other situations, it may be ideal. As far as I know, the physics of all in native iOS applications (for example, messages, etc.) now uses UIKit Dynamics, so for me it’s worth having the “UIView bouncing on spring” handle.




To be clear, of course, you can do something “similar,” just with the animation. Example...

But that just doesn't have the same “physical feel” as the rest of iOS.

-(void)userInputErrorShake { [CATransaction begin]; CAKeyframeAnimation * anim = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; anim.values = @[ [NSValue valueWithCATransform3D: CATransform3DMakeTranslation(-4.0f, 0.0f, 0.0f) ], [NSValue valueWithCATransform3D: CATransform3DMakeTranslation(4.0f, 0.0f, 0.0f) ] ]; anim.autoreverses = YES; anim.repeatCount = 1.0f; anim.duration = 0.1f; [CATransaction setCompletionBlock:^{}]; [self.layer addAnimation:anim forKey:nil]; [CATransaction commit]; } 
+3
ios ios7 user-experience game-physics uikit-dynamics
Jun 22 '14 at 21:46
source share
1 answer

If you want to use UIKit Dynamics, you can:

  • First define a control animator:

     @property (nonatomic, strong) UIDynamicAnimator *animator; 

    And create an instance:

     self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; 
  • Secondly, add the application behavior to this animator to view at the current location. This will make it spring back when clicked. You will have to play with the 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 ​​are not entirely correct, but perhaps this is the starting point in your experiment.

  • Apply push behavior ( UIPushBehaviorModeInstantaneous ) to break it. After that, the binding behavior will lead 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 fading curve doesn't seem completely true to me). I would tend to use block-based animation to move it one way (using UIViewAnimationOptionCurveEaseOut ), when done, initiate the other to move it in the opposite direction (using UIViewAnimationOptionCurveEaseInOut ), and then when done usingSpringWithDamping execute animateWithDuration him to the starting place. IMHO, which gives a curve that looks more like "shake if you make a mistake."

+8
Jun 23 '14 at 14:15
source share



All Articles