简体   繁体   English

摇动UIView ......但是使用UIKit Dynamics

[英]Shake a UIView … BUT using UIKit Dynamics

There are many situations where you need to "shake" a UIView. 在很多情况下你需要“摇动”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? 使用UIKit Dynamics可以做到这一点吗?

So you'd have to .. 所以你必须......

  • take the view, say at 0,0 采取观点,比如说0,0

  • add a spring concept 添加一个春天的概念

  • give it a nudge, say to the "left" 给它一个轻推,对“左”说

  • it should swing back and fore on the spring, ultimately settling again to 0,0 它应该在弹簧上向后摆动,最终再次稳定在0,0

Is this possible? 这可能吗? I couldn't find an example in the Apple demos. 我在Apple演示中找不到一个例子。 Cheers 干杯

Please note that as Niels astutely explains below, a spring is not necessarily the "physics feel" you want for some of these situations: in other situations it may be perfect. 请注意,正如Niels在下面明确地解释的那样,弹簧不一定是你想要的某些情况的“物理感觉”:在其他情况下它可能是完美的。 As far as I know, all physics in iOS's own apps (eg Messages etc) now uses UIKit Dynamics, so for me it's worth having a handle on "UIView bouncing on a spring". 据我所知,iOS自己的应用程序(例如消息等)中的所有物理现在都使用了UIKit Dynamics,所以对我而言,值得一提的是“UIView在弹簧上弹跳”。


Just to be clear, of course you can do something "similar", just with an animation. 为了清楚起见,当然你可以做一些“相似”的事情,只需动画即可。 Example... 例...

But that simply doesn't have the same "physics feel" as the rest of iOS, now. 但现在,这与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];
    }

If you want to use UIKit Dynamics, you can: 如果您想使用UIKit Dynamics,您可以:

  • 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. 您必须使用dampingfrequency值。

     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. 应用推送行为( UIPushBehaviorModeInstantaneous )来扰乱它。 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. 我倾向于基于使用块动画来移动它沿一个方向(与UIViewAnimationOptionCurveEaseOut ),完成后启动另一个到它在相反的方向移动(与UIViewAnimationOptionCurveEaseInOut ),然后的完成时,可以使用usingSpringWithDamping的再现animateWithDuration移动它回到原来的位置。 IMHO, that yields a curve that feels more like "shake if wrong" experience. 恕我直言,这产生了一种曲线,感觉更像是“摇晃如果错误”的体验。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM