touchesBegan, touchesEnded, touchesMoved for moving UIView

Matrosov Alexander picture Matrosov Alexander · Feb 13, 2013 · Viewed 86.9k times · Source

I need to drag my UIView object. I use this code, but it does not work

float oldX, oldY;
BOOL dragging;

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

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self];

    if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
        UILabel *label = (UILabel *)touch.view;
        if (CGRectContainsPoint(label.frame, touchLocation)) {
            dragging = YES;
            oldX = touchLocation.x;
            oldY = touchLocation.y;
        }
    }


}

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

    dragging = NO;
}

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

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self];

    if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
        UILabel *label = (UILabel *)touch.view;

        if (dragging) {
            CGRect frame = label.frame;
            frame.origin.x = label.frame.origin.x + touchLocation.x - oldX;
            frame.origin.y =  label.frame.origin.y + touchLocation.y - oldY;
            label.frame = frame;
        }

    }


}

Answer

Jaybit picture Jaybit · Feb 13, 2013

I would suggest using a UIPanGestureRecognizer:

-(void)dragging:(UIPanGestureRecognizer *)gesture
{
    // Check if this is the first touch
    if(gesture.state == UIGestureRecognizerStateBegan)
    {
        // Store the initial touch so when we change positions we do not snap
        self.panCoord = [gesture locationInView:gesture.view];
        [self.view bringSubviewToFront:gesture.view];

    }

    CGPoint newCoord = [gesture locationInView:gesture.view];

    // Create the frame offsets to use our finger position in the view.
    float dX = newCoord.x-self.panCoord.x;
    float dY = newCoord.y-self.panCoord.y;

    gesture.view.frame = CGRectMake(gesture.view.frame.origin.x+dX,
                                    gesture.view.frame.origin.y+dY,
                                    gesture.view.frame.size.width, 
                                    gesture.view.frame.size.height);
}

This is just a preference of mine. To me it is a lot simpler using a gesture recognizer then using touchesBegan, touchesEnded, touchesMoved. I will use these in cases where the UIPanGestureRecognizer will not work.