Umair Afzal
Umair Afzal

Reputation: 5039

dragging images around the screen using swift

I have tried this method

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {

 let translation = recognizer.translationInView(self.view)
 if let view = recognizer.view {
  view.center = CGPoint(x:view.center.x + translation.x,
                        y:view.center.y + translation.y)
}
 recognizer.setTranslation(CGPointZero, inView: self.view)
}

It is working but the problem is that when I use this method on multiple images it create some issues for example, when drag one image and change its position but when I click and drag second image . My first image come back to original position. Here are the images I am getting from a scroll view: When I click second image 1st image also go the original position

enter image description here

I am dragging an image its fine here

enter image description here

Upvotes: 8

Views: 14217

Answers (3)

Jonas Deichelmann
Jonas Deichelmann

Reputation: 3743

Swift 4 and above

In viewDidLoad() set the gesture and the add the following method:

override func viewDidLoad() {
    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.panGesture))
    yourView.addGestureRecognizer(panGesture)
}

@objc func panGesture(sender: UIPanGestureRecognizer) {
    var relativePosition: CGPoint?
    if sender.state == UIGestureRecognizer.State.began {
        let locationInView = sender.location(in: super.view)
        relativePosition = CGPoint(x: locationInView.x - (sender.view?.center.x ?? 0.0), y: locationInView.y - (sender.view?.center.y ?? 0.0))
        return
    }
    if sender.state == UIGestureRecognizer.State.ended {
        relativePosition = nil
        return
    }
    let locationInView = sender.location(in: super.view)
    guard let pos = relativePosition else {
        return
    }
    sender.view?.center = CGPoint(x: locationInView.x - pos.x,
                                  y: locationInView.y - pos.y)
}

Upvotes: 0

Sachin Nikumbh
Sachin Nikumbh

Reputation: 1051

class DraggableImageView: UIImageView {


var dragStartPositionRelativeToCenter : CGPoint?

override init(image: UIImage!) {
    super.init(image: image)

    self.userInteractionEnabled = true   //< w00000t!!!1

    addGestureRecognizer(UIPanGestureRecognizer(target: self, action: "handlePan:"))

    layer.shadowColor = UIColor.blackColor().CGColor
    layer.shadowOffset = CGSize(width: 0, height: 3)
    layer.shadowOpacity = 0.5
    layer.shadowRadius = 2
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func handlePan(nizer: UIPanGestureRecognizer!) {
    if nizer.state == UIGestureRecognizerState.Began {
        let locationInView = nizer.locationInView(superview)
        dragStartPositionRelativeToCenter = CGPoint(x: locationInView.x - center.x, y: locationInView.y - center.y)

        layer.shadowOffset = CGSize(width: 0, height: 20)
        layer.shadowOpacity = 0.3
        layer.shadowRadius = 6

        return
    }

    if nizer.state == UIGestureRecognizerState.Ended {
        dragStartPositionRelativeToCenter = nil

        layer.shadowOffset = CGSize(width: 0, height: 3)
        layer.shadowOpacity = 0.5
        layer.shadowRadius = 2

        return
    }

    let locationInView = nizer.locationInView(superview)

    UIView.animateWithDuration(0.1) {
        self.center = CGPoint(x: locationInView.x - self.dragStartPositionRelativeToCenter!.x,
            y: locationInView.y - self.dragStartPositionRelativeToCenter!.y)
    }
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/   
}

Upvotes: 9

vacawama
vacawama

Reputation: 154593

Auto Layout is running a putting your images back to where the constraints say they should be.

The easiest way to get around this is to create your images in code instead of creating them in the Storyboard.

Something like:

let lightBulb = UIImageView(frame: CGRectMake(100, 100, 50, 50))
lightBulb.image = UIImage(named: "lightBulb")
lightBulb.contentMode = .ScaleToFill
lightBulb.userInteractionEnabled = true

lightBulb.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: "handlePan:"))

self.view.addSubview(lightBulb)

Upvotes: 8

Related Questions