Drag Views with Gestures iOS Tutorial

The strength of iOS lies in the interaction using touches and gestures. In this tutorial we'll display some custom views, which we can drag using the pan gesture recognizer. This tutorial is made with Xcode 10 and built for iOS 12.

Open Xcode and create a new Single View App.

For product name, use IOSDragViewsGesturesTutorial and then fill out the Organization Name and Organization Identifier with your customary values. Enter Swift as Language and choose Next.

First, let's create the views which we will place randomly on the screen. Add a new class file to the project with File->New -> File -> iOS -> Cocoa Touch Class. Name the class CustomView with a subclass of UIView.

Go to the CustomView.swift file and add a the following property.

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

This variable will keep track of the last position of a user's touch. Next, implement the init method

 override init(frame: CGRect) {
    super.init(frame: frame)

    // Initialization code
    let panRecognizer = UIPanGestureRecognizer(target:self, action:#selector(detectPan))
    self.gestureRecognizers = [panRecognizer]

    //randomize view color
    let blueValue = CGFloat.random(in: 0 ..< 1)
    let greenValue = CGFloat.random(in: 0 ..< 1)
    let redValue = CGFloat.random(in: 0 ..< 1)

    self.backgroundColor = UIColor(red:redValue, green: greenValue, blue: blueValue, alpha: 1.0)
}

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

First we attach a pan gesture recognizer to the view. Using this recognizer we can click and drag a view to a new position. Next, we create a random color, which we assign to the background color property of our view. implement the detectPan method, which will be called when a pan gesture is recognized.

@objc func detectPan(_ recognizer:UIPanGestureRecognizer) {
    let translation  = recognizer.translation(in: self.superview)
    self.center = CGPoint(x: lastLocation.x + translation.x, y: lastLocation.y + translation.y)
}

The translation variable detects the new coordinates of the view when panning. The center of the view will be adjusted according to the changed coordinates. When the user clicks on a view the touchesBegan:event method is called. Let's implement this method.

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    // Promote the touched view
    self.superview?.bringSubviewToFront(self)

    // Remember original location
    lastLocation = self.center
}

When the view is clicked, the current view will be displayed in front of the other views and the center of the view will be assigned to the lastlocation variable. Now, our custom view is ready, let's move over to our view controller. Implement the viewDidLoad function in ViewController.swift

override func viewDidLoad() {
    super.viewDidLoad()

    let sizeOfView = 50
    let maxViews = 100

    let statusBarSize = UIApplication.shared.statusBarFrame.size

    // Add the Views
    for _ in 0 ..< maxViews {
        let pointX = Int.random(in: 0 ..< Int(view.bounds.width) - sizeOfView)
        let pointY = Int.random(in: Int(statusBarSize.height) ..< Int(view.bounds.height) - sizeOfView)

        let newView = CustomView(frame: CGRect(x: pointX, y: pointY, width: 50, height: 50))
        view.addSubview(newView)
    }
 }

There will be 100 custom views of size 50 by 50 added to the main view. The custom view will be placed randomly on the main view. Build and Run the project. Click and drag a view and you will see the views will always be in front of the other views.

You can download the source code of the IOS10DraggingViewsTutorial at the ioscreator repository on github.