dragging images around the screen using swift

13,127

Solution 1

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)

Solution 2

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
}
*/   
}
Share:
13,127
Umair Afzal
Author by

Umair Afzal

Happy Coding :-)

Updated on June 27, 2022

Comments

  • Umair Afzal
    Umair Afzal almost 2 years

    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

  • Umair Afzal
    Umair Afzal over 8 years
    i tried this but nothing is showing up on screen i have written this code on the back of a button action
  • vacawama
    vacawama over 8 years
    I just tried this and it does work. Perhaps you should create an @IBOutlet to the content view of the scroll view to make it easier to add items. @IBOutlet weak var contentView: UIView! and hook that to the content view of your scroll view. Then add the lightBulb like this: contentView.addSubview(lightBulb).
  • Umair Afzal
    Umair Afzal over 8 years
    i am getting this "UIScrollView does not have a member named contentView" and i want to pick the images from scroll view and then display it to the main view
  • vacawama
    vacawama over 8 years
    The addSubview call should be on whichever view you want to display the images. I misunderstood and thought you want to display them on the scrollView. self.view.addSubview(lightBulb) instead.
  • Umair Afzal
    Umair Afzal over 8 years
    i did this : self.view.addsubview(lightbulb) now image is showing on view but when i drag it, it move too fast and disappear from the screen
  • vacawama
    vacawama over 8 years
    Check your panHandler routine. It sounds like you are missing the recognizer.setTranslation(CGPointZero, inView: self.view) part.
  • n4zg
    n4zg about 7 years
    How can i use this class?
  • Khushbu Desai
    Khushbu Desai over 6 years
    @vacawama Thanks, I have used your code now i want to set boundaries for that image i mean i have image inside one view so now i want to make it drag able within that view only, How do i achieve this?