11

私は自動レイアウトにかなり慣れていないので、ビューをアニメーション化する方法について混乱しています。

layoutIfNeeded私は多くのことを読んで、制約を保持し、編集し、UIViewアニメーション ブロックにラップする必要があることを知っています。

でもやろうとなると、ちょっと迷います。たとえば、このアニメーションがどのように行われるかを誰かが説明してくれれば幸いです。

UIPanGestureRecognizerおそらく a を使用して、先頭のスペースからコンテナーへの制約を変更すると思いますconstantが、おそらく UIDynamics を使用します (右側のバウンス効果のために?)。

4

1 に答える 1

16

UIPanGestureRecognizerまあ、同様の動作は+で実現できます[UIView animateWithDuration:animations:]。はい、先頭のスペースの制約を設定し、UIPanGestureRecognizer状態に応じて変更します。最終的な制約のみを設定する必要があることに注意してください (スライダーの最終的な位置を定義します)。アニメーションの中間位置が自動的に計算されます。スライダーには、デフォルトの左位置とアクティブ化された中央位置があります。

ビューの回転には、transformのプロパティを使用できますUIView

IB のオートレイアウトの制約:

IB のオートレイアウトの制約

アニメーション オプション (UIViewAnimationOptionCurveEaseOutアニメーション カーブ) を設定すると、バウンス効果の感覚が得られます。UIPanGestureRecognizerコード (インスタンス変数の宣言は省略します。名前は一目瞭然です):

- (IBAction)onPan:(UIPanGestureRecognizer*)sender
{
    switch (sender.state) {
        case UIGestureRecognizerStateBegan:
            _startOffset = self.leadingSpace.constant;
            _maxOffset = self.slider.superview.frame.size.width
                - kHorizontalPadding
                - self.slider.frame.size.width;
            break;

        case UIGestureRecognizerStateChanged: {
            CGFloat offset = _startOffset + [sender translationInView:self.slider.superview].x;
            offset = MIN(offset, _maxOffset);

            self.leadingSpace.constant = offset;
            break;
        }

        case UIGestureRecognizerStateEnded: {
            CGFloat offset = _startOffset + [sender translationInView:sender.view.superview].x;
            UIColor *bgColor = [UIColor lightGrayColor];
            CGFloat rotation = 0;

            if (offset < _maxOffset) {
                offset = kHorizontalPadding;
            }
            else {
                offset = (_maxOffset + kHorizontalPadding)/2;
                bgColor = [UIColor redColor];
                rotation = M_PI_2;
            }

            self.leadingSpace.constant = offset;

            [UIView
             animateWithDuration:.5
             delay:0
             options:UIViewAnimationOptionCurveEaseOut
             animations:^{
                 [self.slider layoutIfNeeded];
                 self.slider.backgroundColor = bgColor;
                 self.slider.transform = CGAffineTransformMakeRotation(rotation);
             } completion:nil];

            break;
        }

        default:
            break;
    }
}

アニメーション結果UIViewAnimationOptionCurveLinear(キャプチャ シミュレータ):

アニメーション結果

アニメーション結果UIViewAnimationOptionCurveEaseOut(キャプチャ シミュレータ):

アニメーション結果

UIDynamics

UIDynamics を使用すると、事態はさらに複雑になります。良い出発点はRay Wenderlich UIKit Dynamics Tutorialです。

跳ねるスライダーの場合、次の動作を追加できます。

  • UIGravityBehaviorスライダーを開始位置に引っ張ります。angle重力を左に向けるようにプロパティを変更する必要があります。
  • UICollisionBehavior許可された動きの左端と右端を定義します。translatesReferenceBoundsIntoBoundaryプロパティは、親ビューを境界として扱う場合に役立ちます。addBoundaryWithIdentifier:fromPoint:toPointまた、 (またはベジエパス)を使用してスライダーを途中で停止するために、余分な境界を追加する必要があります。
  • UIDynamicItemBehaviorプロパティを変更elasticyして、resistanceバウンスと加速をそれぞれ設定します。
  • おそらくレコグナイザーUIPushBehaviorと組み合わせてvelocityInView:、ユーザーがスライダーを離したときにスライダーの速度を指定します
  • おそらくUISnapBehavior代替手段としてUIGravityBehavior
于 2014-02-15T21:04:33.687 に答える