Drag and Drop Tutorial for macOS

The drag-and-drop mechanism has always been an integral part of Macs. Learn how to adopt it in your apps with this drag and drop tutorial for macOS. By Warren Burton.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Accept the New Type

Next, you have to let the destination view accept this new type. By now, you already know how to do it.

Open DestinationView.swift and add SparkleDrag.type to the registered types. Replace the following line:

var nonURLTypes: Set<String>  { return [String(kUTTypeTIFF)] }

With this:

var nonURLTypes: Set<String>  { return [String(kUTTypeTIFF),SparkleDrag.type] }

Now SparkleDrags are acceptable!

performDragOperation(:_) needs a new else-if clause, so add this code at the end of the method just before return false:

else if let types = pasteBoard.types, types.contains(SparkleDrag.type),
  let action = pasteBoard.string(forType: SparkleDrag.type) {
  delegate?.processAction(action, center:point)
  return true
}

This addition extracts the string from the pasteboard. If it corresponds to your custom type, you pass the action back to the delegate.

You’re almost done, you just need to update StickerBoardViewController to deal with the action instruction.

Handle the Action Instruction

Open StickerBoardViewController.swift and replace processAction(_:center:) with this:

 
func processAction(_ action: String, center: NSPoint) {
  //1.
  if action == SparkleDrag.action  {
    invitationLabel.isHidden = true
    
    //2.
    if let image = NSImage(named:"star") {
      
      //3.
      for _ in 1..<Appearance.numStars {
        
        //A.
        let maxSize:CGFloat = Appearance.maxStarSize
        let sizeChange = CGFloat(arc4random_uniform(Appearance.randonStarSizeChange))
        let finalSize = maxSize - sizeChange
        let newCenter = center.addRandomNoise(Appearance.randomNoiseStar)
        
        //B.
        let imageFrame = NSRect(x: newCenter.x, y: newCenter.y, width: finalSize , height: finalSize)
        let imageView = NSImageView(frame:imageFrame)
        
        //C.
        let newImage = image.tintedImageWithColor(NSColor.randomColor())
        
        //D.
        imageView.image = newImage
        targetLayer.addSubview(imageView)
      }
    }
  }
}

The above code does the following:

  1. Only responds to the known sparkle action
  2. Loads a star image from the bundle
  3. Makes some copies of the star image and…
    1. Generates some random numbers to alter the star position.
    2. Creates an NSImageView and sets its frame.
    3. Gives the image a random color -- unless you're going for a David Bowie tribute, black stars are a bit gothic.
    4. Places the image on the view.
  1. Generates some random numbers to alter the star position.
  2. Creates an NSImageView and sets its frame.
  3. Gives the image a random color -- unless you're going for a David Bowie tribute, black stars are a bit gothic.
  4. Places the image on the view.

Build and run. Now you can drag from the sparkles view onto the sticker view to add a spray of stars to your view.

final

Where to go From Here?

Congratulations, you created a custom drag and drop interface in your very own app!

You can use the Save Image To Desktop button to save your image as a JPG with the name StickerDrag. Maybe take it a step further and tweet it to the team @rwenderlich.

Here's the source code for the the completed project.

This drag and drop tutorial for macOS covered the basics of the Cocoa drag and drop mechanism, including:

  • Creating a dragging destination and accepting several different types of data
  • Using the dragging session lifecycle to provide user feedback of the drag operation
  • Decoding information from the pasteboard
  • Creating a dragging source and providing deferred data
  • Creating a dragging source that provides a custom data type

Now you have the knowledge and experience needed to support drag and drop in any macOS app.

There's certainly more to learn.

You could study up on how to apply effects, such as changing the dragging image during the drag or implementing an animated drop transition, or working with promised files -- Photos is one application that places promised data on the dragging pasteboard.

Another interesting topic is how to use drag and drop with NSTableView and NSOutlineView, which work in slightly different ways. Learn about it from the following resources:

If you have any questions or comments about this drag and drop tutorial for macOS, please join the discussion below! And remember, sometimes life is a dragging experience, but everything's better with unicorns and sparkles. :]