Skip to content

Instantly share code, notes, and snippets.

@raxityo
Created February 5, 2019 18:56
Show Gist options
  • Save raxityo/b50141880f543dcf41c44b08611e841c to your computer and use it in GitHub Desktop.
Save raxityo/b50141880f543dcf41c44b08611e841c to your computer and use it in GitHub Desktop.
Sample ViewController to simulate simple Drag and Drop.
import UIKit
class DragAndDropViewController: UIViewController, UIGestureRecognizerDelegate {
private var sourceView: UIView!
private var dropArea: UIView!
private var objectSize = CGSize(width: 100, height: 100)
private var originalPosition = CGPoint.zero
override func loadView() {
self.view = UIView()
}
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
private func setupView() {
// Initialize
sourceView = UIView(frame: CGRect(origin: .zero, size: objectSize))
sourceView.backgroundColor = .red
dropArea = UIView(frame: CGRect(origin: CGPoint(x: 250, y: 500), size: objectSize))
dropArea.backgroundColor = .blue
// Add Gesture
sourceView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(didLongPressSource)))
// setup root
view.addSubview(dropArea)
view.addSubview(sourceView)
}
var touchOffset = CGPoint.zero
@objc private func didLongPressSource(gesture: UIGestureRecognizer) {
switch(gesture.state) {
case .began:
touchOffset = gesture.location(in: sourceView)
case .changed:
// 1. get moved position
let location = gesture.location(in: view) - touchOffset
// 2. Move there
sourceView.frame.origin = location
case .ended:
// 1. get current position
let location = gesture.location(in: view) - touchOffset
// 2. check if we're closer to start or the end
let distanceFromOrigin = location.distance(from: originalPosition)
let distanceFromDropZone = location.distance(from: dropArea.frame.origin)
let targetPosition = distanceFromOrigin > distanceFromDropZone ? dropArea.frame.origin : originalPosition
// 3. move to the closest point
UIView.animate(withDuration: 0.3) {
self.sourceView.frame.origin = targetPosition
}
default:
break
}
}
}
extension CGPoint {
func distance(from anotherPoint: CGPoint) -> CGFloat {
let dx = abs(x - anotherPoint.x)
let dy = abs(y - anotherPoint.y)
return sqrt(dx*dx + dy*dy)
}
static func +(_ one: CGPoint,_ other: CGPoint) -> CGPoint {
return CGPoint(x: one.x + other.x, y: one.y + other.y)
}
static func -(_ one: CGPoint,_ other: CGPoint) -> CGPoint {
return CGPoint(x: one.x - other.x, y: one.y - other.y)
}
}
// To use this VC in a playground:
import PlaygroundSupport
PlaygroundPage.current.liveView = DragAndDropViewController()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment