2012-11-17 28 views
2

我需要的是當UIImageView從屏幕上拖出時,它會在放開時彈回。我在左邊和上邊工作,這是我正在做的事情。將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]; 

     } 
    } 
} 

所以,我想實現右側和底側的相同的事情。但我一直堅持這一點。有任何想法嗎?

回答

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]; 
    } 
} 

當我讀到你的代碼,邏輯「如果關閉左側,回到將其移動到相同的距離是關閉屏幕的看法。」說實話,這對我來說並不合適(爲什麼當反彈時,座標取決於屏幕有多遠),但我試圖在「屏幕右側」對其進行兌現,並且「屏幕底部」邏輯。顯然,我的邏輯是使用superviewimageView來確定包含視圖的寬度,但如果不合適,請將其替換爲任何內容。

編輯:

我親自做這個東西與手勢識別,如:

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; 
     }]; 
    } 
} 

或者,如果你想要一個手勢識別器,只是防止首先從屏幕上拖出圖像,它就會LD是:

- (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,您可以通過使用新的animationWithDurationusingSpringWithDampeninginitialSpringVelocity參數給圖像視圖的動畫回到它原來的位置一點點反彈力:

[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的動態添加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]; 
+0

這很好,我唯一遇到的問題是self.view在縱向時給人像尺寸。 CGRectContainsRect(self.view.frame,imageView.frame) – Jonathan

+0

旋轉始終是一個惱人的問題。順便說一句,如果我的答案適合你,請接受它,謝謝。 – sunkehappy

+0

@Jonathan我的代碼不使用'self.view.frame',所以我不確定我是否關注你。我正在使用'imageView.superview.frame',但是你是否說即使在景觀中它也返回縱向尺寸? – Rob

1

我認爲最簡單的方法是檢查您的imageView是否已經從您的self.view中消失。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    if (!CGRectContainsRect(self.view.frame, imageView.frame)){ 
     // Your animation to bounce. 
    } 
} 
+0

我假設這個問題不僅僅是如何確定圖像是否已經移動到屏幕外的位置,還有如何確定新的位置。 – Rob