【问题标题】:Disable rotation on a UISnapBehavior?在 UISnapBehavior 上禁用旋转?
【发布时间】:2013-10-02 15:51:48
【问题描述】:

我喜欢UISnapBehaviorsn-p,但我真的很想用它在一个方向轻轻摆动。

有没有办法关闭这种行为的旋转? 因为SpriteKit 具有allowsRotation 属性,可以轻松关闭。

【问题讨论】:

    标签: animation ios7 uikit uikit-dynamics


    【解决方案1】:

    您可以通过将UIDynamicItemBehavior 添加到您的UIDynamicAnimator 然后将其allowsRotation 属性设置为NO 来做到这一点,如下所示:

    UIDynamicItemBehavior * dynamicItem = [[UIDynamicItemBehavior alloc] initWithItems:@[self.viewToSnap]];
    dynamicItem.allowsRotation = NO;
    [self.animator addBehavior:dynamicItem];
    

    【讨论】:

    • 同意,这是在UISnapBehavior 中停止旋转的技术。如果您有其他需要遵守的 UIKit Dynamics 行为(例如 UICollisionBehavior),那么这是正确的答案,因为在其他地方建议的 animateWithDuration 不会遵守您可能拥有的其他行为。
    【解决方案2】:

    这里有一个更好的答案:UISnapBehavior 有一个 action 属性,它接受一个在每一步都被调用的块。像这样设置这个块...

    snapBehavior.action = ^{ view.transform = CGAffineTransformIdentity; };
    

    ... 导致旋转无效,没有任何其他副作用。

    【讨论】:

      【解决方案3】:

      不需要UIKitDynamics

      只需使用:

      [UIView animateWithDuration:0.5
                                delay:0.0
               usingSpringWithDamping:0.65
                initialSpringVelocity:0.5
                              options:0
                           animations:^
          {
              self.transform = (self.expanded) ? self.openedTransition : self.closedTransition;
          }
                            completion:nil];
      

      【讨论】:

      • 同意,如果你想要的只是弹簧效果,这比使用 UIKit Dynamics 更简单。
      【解决方案4】:

      我自己也在寻找相同的解决方案,但是在 UIDynamicItemBehavior 上设置 allowsRotation 并没有完全达到我想要的效果。

      我能够通过使用 UICollisionBehavior 并在我不想移动的视图的任一侧放置两个边界来防止 UISnapBehavior 的任何移动(在我的情况下,我在左侧和右侧配置了边界防止 x 轴移动)。为了获得良好的弹跳效果,我还将friction 设置为0(使用UIDynamicItemBehavior)并调整UISnapBehavior 上的damping 以获得正确的弹跳量。

      这是一个对我有用的例子:

      [self.animator removeAllBehaviors];
      
      UISnapBehavior *snapBackBehavior = [[UISnapBehavior alloc] initWithItem:self.snappingView snapToPoint:self.slidePanelCenter];
      snapBackBehavior.damping = 0.2;
      [self.animator addBehavior:snapBackBehavior];
      
      UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.snappingView]];
      itemBehavior.friction = 0.0;
      [self.animator addBehavior:itemBehavior];
      
      CGPoint leftBoundaryStart  = CGPointMake(self.snappingView.frame.origin.x, 0.0);
      CGPoint leftBoundaryEnd    = CGPointMake(leftBoundaryStart.x, self.view.bounds.size.height);
      CGPoint rightBoundaryStart = CGPointMake(leftBoundaryStart.x + self.snappingView.frame.size.width, 0.0);
      CGPoint rightBoundaryEnd   = CGPointMake(rightBoundaryStart.x, leftBoundaryEnd.y);
      
      UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.snappingView]];
      [collisionBehavior addBoundaryWithIdentifier:@"leftEdge" fromPoint:leftBoundaryStart toPoint:leftBoundaryEnd];
      [collisionBehavior addBoundaryWithIdentifier:@"rightEdge" fromPoint:rightBoundaryStart toPoint:rightBoundaryEnd];
      [self.animator addBehavior:collisionBehavior];
      

      【讨论】:

        【解决方案5】:

        UIView 符合 UIDynamicItem,它具有在进行旋转时调用的 transform 属性。所以重写 setTransform: 虚无......

        - (void)setTransform:(CGAffineTransform)transform
        {
        }
        

        ... 停止旋转,但可能会产生未知和不良的副作用。需要一些方法来检查动态动画是否正在进行中。

        在前往新位置的途中,仍然会有一些平行于移动方向的弹跳运动。

        如果我们可以控制旋转/弹跳效果的数量,那就太好了,因为它本来就很卡通。

        【讨论】:

          猜你喜欢
          • 2016-01-23
          • 2012-07-21
          • 2011-03-20
          • 1970-01-01
          • 2012-04-21
          • 2018-07-03
          • 2011-05-06
          • 2019-04-28
          • 1970-01-01
          相关资源
          最近更新 更多