2011-07-13 17 views
71

Có một số ví dụ về lớp học UIPanGestureRecognizer. Ví dụ tôi đã đọc this và tôi vẫn không thể sử dụng nó ...Cách sử dụng UIPanGestureRecognizer để di chuyển đối tượng? iPhone/iPad

Trên tệp nib mà tôi đang làm việc trên tôi có UIView (hình chữ nhật màu trắng trên hình ảnh) mà tôi muốn kéo với lớp đó:

enter image description here

và trong file .m của tôi, tôi đã đặt:

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

và phương pháp mà không được thực thi khi tôi kéo chuột trên UIView. Tôi cũng đã thử đặt:

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

Và phương pháp đó cũng không được thực thi. Có lẽ tôi sai nhưng tôi nghĩ rằng phương pháp này nên hoạt động như phương pháp - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event nơi tôi chỉ cần đặt phương thức đó và nó sẽ được gọi bất cứ khi nào có chạm.

Tôi đang làm gì sai? Có lẽ tôi phải vẽ một kết nối với phương pháp đó? Nếu vậy làm thế nào tôi có thể làm điều đó?

Trả lời

130

Tôi đã tìm thấy hướng dẫn Working with UIGestureRecognizers và tôi nghĩ đó là những gì tôi đang tìm kiếm. Nó đã giúp tôi đưa ra các giải pháp sau đây:

-(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

Tuyệt vời !! Tôi thích tính toán của animationDuration, hoạt động tốt. – dan

+36

Nếu bạn thay đổi di chuyển: (id) người gửi phải di chuyển: (UIPanGestureRecognizer *), người gửi bạn không phải làm tất cả những kiểu gõ xấu xí đó. – Wex

+1

Giải pháp này không hoạt động đối với UISwitch. Ngoài ra tôi đã thử thực hiện touchesBegan, touchesMoved phương pháp nhưng không thể di chuyển UISwitch. Bạn có thể vui lòng cho tôi biết làm thế nào tôi có thể di chuyển UISwitch chỉ bằng cách kéo? – 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

chiến thắng hoàn hảo! – MaKo

+0

Không thể tranh luận với sự đơn giản, nhưng giải pháp này có vấn đề: ngay khi bạn đặt ngón tay xuống để bắt đầu cử chỉ, 'image1' sẽ nhảy, có khả năng khá xa, sao cho trung tâm của nó nằm dưới ngón tay bạn. Tốt hơn là điều chỉnh 'image1.center' bằng bản dịch' pan' để có trải nghiệm tiêu chuẩn và chất lỏng hơn. – 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

Đối với 'CGPointMake (0, 0)' bạn có thể viết 'CGRectZero'. –

+2

@ ý nghĩa-vấn đề Bạn không có nghĩa là 'CGPointZero'? – mylogon

+1

@mylogon Bạn hoàn toàn đúng. Tôi sẽ đưa ra một số câu trả lời của bạn như lời cảm ơn của tôi. –

-2

Phiên bản Swift 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

nhanh chóng 2 phiên bản của câu trả lời @MS AppTech

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) 
} 
Các vấn đề liên quan