2011-07-13 4 views
71

UIPanGestureRecognizerクラスのいくつかの例があります。たとえば、私はthisを読みましたが、まだ使用できません...UIPanGestureRecognizerを使用してオブジェクトを移動するにはどうすればよいですか? iPhone/iPad

私が取り組んでいるnibファイルでは、そのクラスでドラッグしたいUIView(画像の白い四角形)があります:

enter image description here

と私の.mファイル内

は、私が置かれています:

- (void)setTranslation:(CGPoint)translation inView:(UIView *)view 
{ 
    NSLog(@"Test to see if this method gets executed"); 
} 

と私はUIView全体でマウスをドラッグすると、そのメソッドは実行されません。私はまた、配置しようとしました:

- (void)pan:(UIPanGestureRecognizer *)gesture 
{ 
    NSLog(@"testing"); 
} 

そして、その方法も実行されません。たぶん私は間違っていますが、私はこのメソッドが- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)eventメソッドのように機能し、そのメソッドを置くだけでよく、触れているときはいつでも呼び出されると思います。

私は間違っていますか?たぶん私はそのメソッドへの接続を描画する必要がありますか?もしそうなら、どうしたらいい?

答えて

130

私はチュートリアルWorking with UIGestureRecognizersを見つけました。それは私が探しているものだと思います。それは私には、次の解決策を考え出す助け:

-(IBAction) someMethod { 
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)]; 
    [panRecognizer setMinimumNumberOfTouches:1]; 
    [panRecognizer setMaximumNumberOfTouches:1]; 
    [ViewMain addGestureRecognizer:panRecognizer]; 
    [panRecognizer release]; 
} 

-(void)move:(UIPanGestureRecognizer*)sender { 
    [self.view bringSubviewToFront:sender.view]; 
    CGPoint translatedPoint = [sender translationInView:sender.view.superview]; 

    if (sender.state == UIGestureRecognizerStateBegan) { 
     firstX = sender.view.center.x; 
     firstY = sender.view.center.y; 
    } 


    translatedPoint = CGPointMake(sender.view.center.x+translatedPoint.x, sender.view.center.y+translatedPoint.y); 

    [sender.view setCenter:translatedPoint]; 
    [sender setTranslation:CGPointZero inView:sender.view]; 

    if (sender.state == UIGestureRecognizerStateEnded) { 
     CGFloat velocityX = (0.2*[sender velocityInView:self.view].x); 
     CGFloat velocityY = (0.2*[sender velocityInView:self.view].y); 

     CGFloat finalX = translatedPoint.x + velocityX; 
     CGFloat finalY = translatedPoint.y + velocityY;// translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y); 

     if (finalX < 0) { 
      finalX = 0; 
     } else if (finalX > self.view.frame.size.width) { 
      finalX = self.view.frame.size.width; 
     } 

     if (finalY < 50) { // to avoid status bar 
      finalY = 50; 
     } else if (finalY > self.view.frame.size.height) { 
      finalY = self.view.frame.size.height; 
     } 

     CGFloat animationDuration = (ABS(velocityX)*.0002)+.2; 

     NSLog(@"the duration is: %f", animationDuration); 

     [UIView beginAnimations:nil context:NULL]; 
     [UIView setAnimationDuration:animationDuration]; 
     [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; 
     [UIView setAnimationDelegate:self]; 
     [UIView setAnimationDidStopSelector:@selector(animationDidFinish)]; 
     [[sender view] setCenter:CGPointMake(finalX, finalY)]; 
     [UIView commitAnimations]; 
    } 
} 
+0

素晴らしい!私はanimationDurationの計算が大好きです。 – dan

+36

移動:(id)送信者を移動:(UIPanGestureRecognizer *)送信者に変更すると、その醜い型キャストをすべて行う必要はありません。 – Wex

+1

このソリューションはUISwitchでは機能しません。また、私はtouchesBegan、touchesMovedメソッドを実装しようとしましたが、UISwitchを動かすことはできませんでした。ドラッグするだけでUISwitchを動かすことができますか? – DShah

34
UIPanGestureRecognizer * pan1 = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(moveObject:)]; 
pan1.minimumNumberOfTouches = 1; 
[image1 addGestureRecognizer:pan1]; 

-(void)moveObject:(UIPanGestureRecognizer *)pan; 
{ 
image1.center = [pan locationInView:image1.superview]; 
} 
+0

完璧な勝利! – MaKo

+0

シンプルさを主張することはできませんが、この解決方法には問題があります。ジェスチャーを開始するために指を置くとすぐに、 'image1'は潜在的にかなり離れて、その中心があなたの指の下に飛びます。より流動的で標準的な経験のために 'pan'の翻訳によって' image1.center'を調整する方が良いでしょう。 – sartak

21
-(IBAction)Method 
{ 
     UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
     [panRecognizer setMinimumNumberOfTouches:1]; 
     [panRecognizer setMaximumNumberOfTouches:1]; 
     [ViewMain addGestureRecognizer:panRecognizer]; 
     [panRecognizer release]; 
} 
- (Void)handlePan:(UIPanGestureRecognizer *)recognizer 
{ 

    CGPoint translation = [recognizer translationInView:self.view]; 
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, 
            recognizer.view.center.y + translation.y); 
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view]; 

    if (recognizer.state == UIGestureRecognizerStateEnded) { 

     CGPoint velocity = [recognizer velocityInView:self.view]; 
     CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y)); 
     CGFloat slideMult = magnitude/200; 
     NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult); 

     float slideFactor = 0.1 * slideMult; // Increase for more of a slide 
     CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor), 
            recognizer.view.center.y + (velocity.y * slideFactor)); 
     finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width); 
     finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height); 

     [UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ 
      recognizer.view.center = finalPoint; 
     } completion:nil]; 

    } 

} 
+3

'CGPointMake(0、0)'では 'CGRectZero'と書くことができます。 –

+2

@ meaning-matters「CGPointZero」を意味しないのですか? – mylogon

+1

@ミロゴンあなたは絶対に正しいです。私はあなたの答えの一部を私の感謝としてお伝えします。 –

-2

スウィフト2バージョン:

// start detecting pan gesture 
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(TTAltimeterDetailViewController.panGestureDetected(_:))) 
panGestureRecognizer.minimumNumberOfTouches = 1 
self.chartOverlayView.addGestureRecognizer(panGestureRecognizer) 

func panGestureDetected(panGestureRecognizer: UIPanGestureRecognizer) { 
    print("pan gesture recognized") 
} 
1
if ([recognizer state] == UIGestureRecognizerStateChanged)  
{ 
    CGPoint translation1 = [recognizer translationInView:main_view]; 
    img12.center=CGPointMake(img12.center.x+translation1.x, img12.center.y+ translation1.y); 
    [recognizer setTranslation:CGPointMake(0, 0) inView:main_view]; 

    recognizer.view.center=CGPointMake(recognizer.view.center.x+translation1.x, recognizer.view.center.y+ translation1.y); 
} 

-(void)move:(UIPanGestureRecognizer*)recognizer 
{ 
    if ([recognizer state] == UIGestureRecognizerStateChanged)  
    { 
     CGPoint translation = [recognizer translationInView:self.view]; 
     recognizer.view.center=CGPointMake(recognizer.view.center.x+translation.x, recognizer.view.center.y+ translation.y); 
     [recognizer setTranslation:CGPointMake(0, 0) inView:self.view]; 
    } 
} 
0

@MS AppTech応答の迅速な2バージョン

func handlePan(panGest : UIPanGestureRecognizer) { 
let velocity : CGPoint = panGest.velocityInView(self.view); 
     let magnitude : CGFloat = CGFloat(sqrtf((Float(velocity.x) * Float(velocity.x)) + (Float(velocity.y) * Float(velocity.y)))); 
     let slideMult :CGFloat = magnitude/200; 
     //NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult); 

     let slideFactor : CGFloat = 0.1 * slideMult; // Increase for more of a slide 
     var finalPoint : CGPoint = CGPointMake(panGest.view!.center.x + (velocity.x * slideFactor), 
             panGest.view!.center.y + (velocity.y * slideFactor)); 
     finalPoint.x = min(max(finalPoint.x, 0), self.view.bounds.size.width); 
     finalPoint.y = min(max(finalPoint.y, 0), self.view.bounds.size.height); 

     UIView.animateWithDuration(Double(slideFactor*2), delay: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: { 
      panGest.view!.center = finalPoint; 
      }, completion: nil) 
} 
関連する問題