2

必要なのは、UIImageViewを画面からドラッグして離すと、元に戻ることです。私はそれを左側と上面で機能させています。これが私がしていることです。

    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {          

        if (!CGRectContainsPoint(self.view.frame, imageView.frame.origin)){  

            CGFloat newX = 0.0f;
            CGFloat newY = 0.0f;

            // If off screen upper and left

            if (imageView.frame.origin.x < 0.0f){
                CGFloat negX = imageView.frame.origin.x * -1;
                newX = negX;
            }else{
                newX = imageView.frame.origin.x;
            }

            if (imageView.frame.origin.y < 0.0f){
                CGFloat negY = imageView.frame.origin.y * -1;
                newY = negY;
            }else{
                newY = imageView.frame.origin.y;
            }


            CGRect newPoint = CGRectMake(newX, newY, imageView.frame.size.width, imageView.frame.size.height);

            [UIView beginAnimations:@"BounceAnimations" context:nil];
            [UIView setAnimationDuration:.5];
            [letterOutOfBounds play];
            [imageView setFrame:newPoint];

            [UIView commitAnimations];

        }
    }
}

ですから、右側と下側で同じことを実現したいと思います。しかし、私はしばらくの間これで立ち往生しています。何か案は?

4

2 に答える 2

6

次のようなものはどうですか?

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    UIImageView *imageView = nil;

    BOOL moved = NO;
    CGRect newPoint = imageView.frame;

    // If off screen left

    if (newPoint.origin.x < 0.0f){
        newPoint.origin.x *= -1.0;
        moved = YES;
    }

    // if off screen up

    if (newPoint.origin.y < 0.0f){
        newPoint.origin.y *= -1.0;
        moved = YES;
    }

    // if off screen right

    CGFloat howFarOffRight = (newPoint.origin.x + newPoint.size.width) - imageView.superview.frame.size.width;
    if (howFarOffRight > 0.0)
    {
        newPoint.origin.x -= howFarOffRight * 2;
        moved = YES;
    }

    // if off screen bottom

    CGFloat howFarOffBottom = (newPoint.origin.y + newPoint.size.height) - imageView.superview.frame.size.height;
    if (howFarOffBottom > 0.0)
    {
        newPoint.origin.y -= howFarOffBottom * 2;
        moved = YES;
    }

    if (moved)
    {
        [UIView beginAnimations:@"BounceAnimations" context:nil];
        [UIView setAnimationDuration:.5];
        [letterOutOfBounds play];
        [imageView setFrame:newPoint];

        [UIView commitAnimations];
    }
}

私があなたのコードを読んでいるとき、「左側から離れている場合は、画面から離れているのと同じ距離だけビューに戻す」というロジックがあります。正直なところ、それは私にはまったく意味がありません(なぜ、跳ね返るとき、座標は画面からどれだけ離れているかに依存します)が、私は「画面外」でそれを尊重しようとしました「画面下部」ロジック。明らかに、私のロジックはsuperviewofを使用してimageView、含まれているビューの幅を決定していますが、それが適切でない場合は、それを何にでも置き換えてください。

編集:

私は個人的に、次のようなジェスチャレコグナイザーを使用してこのようなことを行います。

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.imageView addGestureRecognizer:pan];
self.imageView.userInteractionEnabled = YES;

したがって、画像を元に戻すアニメーションを行うジェスチャレコグナイザーは次のようになります。

- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
    static CGRect originalFrame; // you could make this an ivar if you want, but just for demonstration purposes

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        originalFrame = self.imageView.frame;
    }
    else if (gesture.state == UIGestureRecognizerStateChanged)
    {
        CGPoint translate = [gesture translationInView:gesture.view];

        CGRect newFrame = originalFrame;

        newFrame.origin.x += translate.x;
        newFrame.origin.y += translate.y;

        gesture.view.frame = newFrame;
    }
    else if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled)
    {
        CGRect newFrame = gesture.view.frame;

        newFrame.origin.x = fmaxf(newFrame.origin.x, 0.0);
        newFrame.origin.x = fminf(newFrame.origin.x, gesture.view.superview.bounds.size.width - newFrame.size.width);

        newFrame.origin.y = fmaxf(newFrame.origin.y, 0.0);
        newFrame.origin.y = fminf(newFrame.origin.y, gesture.view.superview.bounds.size.height - newFrame.size.height);

        // animate how ever you want ... I generally just do animateWithDuration

        [UIView animateWithDuration:0.5 animations:^{
            gesture.view.frame = newFrame;
        }];
    }
}

または、そもそも画像が画面からドラッグされないようにするジェスチャレコグナイザーが必要な場合は、次のようになります。

- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
    static CGRect originalFrame;

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        originalFrame = self.imageView.frame;
    }
    else if (gesture.state == UIGestureRecognizerStateChanged)
    {
        CGPoint translate = [gesture translationInView:gesture.view];

        CGRect newFrame = originalFrame;

        newFrame.origin.x += translate.x;
        newFrame.origin.x = fmaxf(newFrame.origin.x, 0.0);
        newFrame.origin.x = fminf(newFrame.origin.x, gesture.view.superview.bounds.size.width - newFrame.size.width);

        newFrame.origin.y += translate.y;
        newFrame.origin.y = fmaxf(newFrame.origin.y, 0.0);
        newFrame.origin.y = fminf(newFrame.origin.y, gesture.view.superview.bounds.size.height - newFrame.size.height);

        gesture.view.frame = newFrame;
    }
}

ちなみに、iOS 7では、パラメーターとパラメーターを指定してnewanimationWithDurationを使用することで、画像ビューのアニメーションを元の場所に戻すことができます。usingSpringWithDampeninginitialSpringVelocity

[UIView animateWithDuration:1.0
                      delay:0.0
     usingSpringWithDamping:0.3
      initialSpringVelocity:0.1
                    options:0
                 animations:^{
                     // set the new `frame` (or update the constraint constant values that
                     // will dictate the `frame` and call `layoutViewsIfNeeded`)
                 }
                 completion:nil];

または、iOS7では、UIKit Dynamicsを使用してUISnapBehavior:を追加することもできます。

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator.delegate = self;

UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.viewToAnimate snapToPoint:CGPointMake(self.viewToAnimate.center.x, self.view.frame.size.height - 50)];

// optionally, you can control how much bouncing happens when it finishes, e.g., for a lot of bouncing:
//
// snap.damping = 0.2;

// you can also slow down the snap by adding some resistance
//
// UIDynamicItemBehavior *resistance = [[UIDynamicItemBehavior alloc] initWithItems:@[self.viewToAnimate]];
// resistance.resistance = 20.0;
// resistance.angularResistance = 200.0;
// [self.animator addBehavior:resistance];

[self.animator addBehavior:snap];
于 2012-11-17T04:01:15.507 に答える
1

最も簡単な方法は、あなたimageViewがあなたの外に出たかどうかを確認することだと思いますself.view

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
    if (!CGRectContainsRect(self.view.frame, imageView.frame)){
        // Your animation to bounce.
    }
}
于 2012-11-17T03:25:37.837 に答える