如何使用UIPangestureRecognitor移动对象?iPhone/iPad

如何使用UIPangestureRecognitor移动对象?iPhone/iPad,iphone,objective-c,ipad,drag,Iphone,Objective C,Ipad,Drag,有几个UIPangestureRecognitor类的示例。例如,我已经阅读,但我仍然无法使用它 在我正在处理的nib文件上,我有一个UIView(图像上的白色矩形),我希望与该类一起拖动: 在我的.m文件中,我放置了: - (void)setTranslation:(CGPoint)translation inView:(UIView *)view { NSLog(@"Test to see if this method gets executed"); } 当我在UIView上拖

有几个
UIPangestureRecognitor
类的示例。例如,我已经阅读,但我仍然无法使用它

在我正在处理的nib文件上,我有一个
UIView
(图像上的白色矩形),我希望与该类一起拖动:

在我的.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*)toucheevent:(UIEvent*)event
方法一样工作,我只需要放置那个方法,只要有触碰就会调用它

我做错了什么?也许我必须和那个方法有联系?如果是这样,我该怎么做

我找到了教程,我想这就是我想要的。它帮助我想出了以下解决方案:

-(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];
    }
}
-(iAction)方法{
UIPangestureRecognitzer*PanRecognitzer=[[UIPangestureRecognitzer alloc]initWithTarget:自操作:@selector(move:)];
[装甲识别器设置最小接触次数:1];
[装甲识别器设置最大接触次数:1];
[ViewMain ADDGESTURE识别器:装甲识别器];
[装甲识别器释放];
}
-(无效)移动:(UIPangestureRecognitor*)发送方{
[self.view将subviewTofront:sender.view];
CGPoint translatedPoint=[sender TranslationView:sender.view.superview];
if(sender.state==UIgestureRecognitizerStateStart){
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设置中心:translatedPoint];
[sender setTranslation:CGPointZero-inView:sender.view];
if(sender.state==UIGestureRecognitizerStateEnded){
CGFloat-velocityX=(0.2*[sender-velocityview:self.view].x);
CGFloat-velocityY=(0.2*[sender-velocityview:self.view].y);
CGFloat finalX=平移点.x+速度x;
CGFloat finalY=translatedPoint.y+velocityY;//translatedPoint.y+(.35*[(UIPangestureRecognitizer*)发送方速度视图:self.view].y);
如果(finalX<0){
finalX=0;
}else if(finalX>self.view.frame.size.width){
finalX=self.view.frame.size.width;
}
如果(最终<50){//避免状态栏
最终=50;
}else if(最终>self.view.frame.size.height){
finalY=self.view.frame.size.height;
}
CGFloat animationDuration=(绝对速度)*.0002)+.2;
NSLog(@“持续时间为:%f”,animationDuration);
[UIView beginAnimations:nil上下文:NULL];
[UIView setAnimationDuration:animationDuration];
[UIView设置动画曲线:UIViewAnimationCurveEaseOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidFinish)];
[[sender view]设置中心:CGPointMake(finalX,finalY)];
[UIView委员会];
}
}
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")
}

@MS AppTech答案的swift 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)
}

几年后,我把帽子扔进了拳击场

需要保存图像视图的起始中心:

var panBegin: CGPoint.zero
然后使用变换更新新中心:

if recognizer.state == .began {
     panBegin = imageView!.center

} else if recognizer.state == .ended {
    panBegin = CGPoint.zero

} else if recognizer.state == .changed {
    let translation = recognizer.translation(in: view)
    let panOffsetTransform = CGAffineTransform( translationX: translation.x, y: translation.y)

    imageView!.center = panBegin.applying(panOffsetTransform)
}

太神了我喜欢计算动画持续时间,效果很好。如果您将move:(id)sender更改为move:(UIPangestureRecognitizer*)sender,则不必进行所有难看的打字。此解决方案不适用于UISwitch。我还尝试实现touchesbreated、touchesMoved方法,但无法移动UISwitch。您能告诉我如何通过拖动来移动UI开关吗?记住对于与手势识别器关联的视图,要让userInteractionEnabled=YES。firstX和firstY是什么?对于
CGPointMake(0,0)
你可以写
CGRectZero
@意思很重要,你不是说
CGRectZero
?@mylogon你完全正确。我会把你的一些回答作为我的感谢。完美无缺的胜利!这种简单性无可争议,但这种解决方案有一个问题:只要你放下手指开始做手势,
image1
就会跳起来,可能跳得很远,以至于它的中心在你的手指下。最好通过
pan
的翻译来调整
image1.center
,以获得更流畅、更标准的体验。
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)
}
var panBegin: CGPoint.zero
if recognizer.state == .began {
     panBegin = imageView!.center

} else if recognizer.state == .ended {
    panBegin = CGPoint.zero

} else if recognizer.state == .changed {
    let translation = recognizer.translation(in: view)
    let panOffsetTransform = CGAffineTransform( translationX: translation.x, y: translation.y)

    imageView!.center = panBegin.applying(panOffsetTransform)
}