Question

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;
        }

    }


}
Was it helpful?

Solution 3

There's something a bit strange in your code.

You ask for the location in self, some UIView which presumably contains the UILabel you want to check. This begs the question as to why you do not add the touchesXXX to some UILabel subclass of yours.

This cancels out as you're using the label.frame which is defined in terms of its superview.bounds (your parent UIView you asked the touch location with respect to), but this doesn't make for the most straightforward way to follow what's going on.

OTHER TIPS

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.

This is work code for move UIView objects

float oldX, oldY; BOOL dragging;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:touch.view];
    if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
        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:touch.view];    
    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;
        }
    }
}

With this code i could move my UIView Object anywhere. My ViewController.swift looks like this.

// code from below

import UIKit

class ViewController: UIViewController {

    var location = CGPoint(x: 0, y: 0)

    @IBOutlet weak var Person: UIImageView!

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        var touch : UITouch! =  touches.first! as UITouch

        location = touch.location(in: self.view)

        Person.center = location

    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        var touch : UITouch! =  touches.first! as UITouch

        location = touch.location(in: self.view)

        Person.center = location
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        Person.center = CGPoint(x: 160, y: 330)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

//ends

Hope it helps although it is another way to do it than the one mentioned in question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top