2

我想使用 touchesbegan、touchesmoved 和 touchesended 方法从我的视图控制器中移动一个对象。它按我想要的方式工作(如果它移动的距离不够大,它将被放置到它的初始位置)但是拖动的动画并不流畅。任何人都可以帮助我,使其成为流畅的拖动动作吗?

这是我的代码:

#pragma mark -
#pragma mark Touch Gestures


- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
    UITouch *touch = [touches anyObject];
    if (touch.view == _topCard) {
        CGPoint touchPoint = [touch locationInView:_topCard];
        touchCenterOffset = CGPointMake([touch view].center.x - touchPoint.x,
                                        [touch view].center.y - touchPoint.y);
        [self animateFirstTouchAtPoint:touchPoint];
    }

}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent *)event {
    UITouch* touch = [touches anyObject];

    if (touch.view == _topCard) {
        CGPoint location = [touch locationInView:_topCard];
        CGPoint pointOnTable = [_topCard convertPoint:[touch locationInView:_topCard] toView:_topCard.superview];
                CGPoint newCenter = CGPointMake(location.x + touchCenterOffset.x,
                                        location.y + touchCenterOffset.y);
        [touch view].center = newCenter;

        if (pointOnTable.x > 180) {
            NSLog(@"Aktionismus");
        } else {
            NSLog(@"KEIN Aktionismus");
        }
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch* touch = [touches anyObject];

    if (touch.view == _topCard) {
        CGPoint pointOnTable = [_topCard convertPoint:[touch locationInView:_topCard] toView:_topCard.superview];

        if (pointOnTable.x > 180) {
            NSLog(@"Aktionismus");
        } else {
            [self animatePutBackTopCard:FLIP_DURATION];
        }
    }
}

- (void) touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
    UITouch* touch = [touches anyObject];

    if (touch.view == _topCard) {
        [self animatePutBackTopCard:FLIP_DURATION];
    }

}

#pragma mark - 
#pragma mark Animations

- (void)animateFirstTouchAtPoint:(CGPoint)touchPoint {
    /*[UIView animateWithDuration:GROW_ANIMATION_DURATION_SECONDS animations:^{
        _topCard.transform = CGAffineTransformScale(_topCard.transform, 1.2, 1.2);
    }];*/
}

- (void)animatePutBackTopCard:(NSTimeInterval)duration {
    [UIView animateWithDuration:duration animations:^{
        CGPoint originalCenter = CGPointMake(ORIGIN_CENTER_X,ORIGIN_CENTER_Y);
        _topCard.center = originalCenter;
    }];
}

非常感谢!

4

5 回答 5

4

最后我弄清楚我的问题出在哪里:

我没有在超级视图中跟踪对象的移动,而是跟踪对象上的接触点。

这是调整后的代码,可以很好地平滑拖动:

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
    UITouch *touch = [touches anyObject];
    if (touch.view == _topCard) {
        translation = [touch locationInView:_topCard.superview];
    }

}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent *)event {
    UITouch* touch = [touches anyObject];

    if (touch.view == _topCard) {
      CGPoint newTranslation = [touch locationInView:_topCard.superview];
      _topCard.frame = CGRectOffset(_topCard.frame, newTranslation.x - translation.x, newTranslation.y - translation.y);
      translation = newTranslation;

    }
}
于 2013-07-24T07:59:03.013 回答
1

看看我是如何移动物体的,它工作顺利:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];

    CGPoint location = [touch locationInView:self.superview];
    float difx = [[touches anyObject] locationInView:self].x - [[touches anyObject] previousLocationInView:self].x;

    float dify = [[touches anyObject] locationInView:self].y - [[touches anyObject] previousLocationInView:self].y;

    CGAffineTransform newTransform1 = CGAffineTransformTranslate(self.transform, difx, dify);

    self.transform = newTransform1;
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView:self.superview];
    float difx = [[touches anyObject] locationInView:self].x - [[touches anyObject] previousLocationInView:self].x;

    float dify = [[touches anyObject] locationInView:self].y - [[touches anyObject] previousLocationInView:self].y;

    CGAffineTransform newTransform1 = CGAffineTransformTranslate(self.transform, difx, dify);

    self.transform = newTransform1;

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

}

我认为你可以适应你的需要。

于 2013-07-17T07:36:04.640 回答
1

我使用以下代码拖动自定义 UIView

应用截图

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];
    CGPoint previous = [touch previousLocationInView:self];

    if (!CGAffineTransformIsIdentity(self.transform)) {
        location = CGPointApplyAffineTransform(location, self.transform);
        previous = CGPointApplyAffineTransform(previous, self.transform);
    }

    self.frame = CGRectOffset(self.frame,
                              (location.x - previous.x),
                              (location.y - previous.y));
}
于 2014-03-23T10:35:15.720 回答
1

如其他答案所述,直接操作视图的框架是不好的做法。例如,在使用 UIDynamics 时会导致非常奇怪的行为。您应该改为设置视图的中心。

  override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {

        let p1 = touch.locationInView(self.superview)
        let p0 = touch.previousLocationInView(self.superview)
        let translation = CGPointMake(p1.x - p0.x, p1.y - p0.y);
        center = CGPointMake(center.x + translation.x, center.y + translation.y)//set views center
    }
}
于 2015-09-02T21:35:50.783 回答
0

对于拖动,我建议改用 panGestureRecognizer。

信息可以在这里找到

于 2013-07-17T07:08:26.053 回答