A Drag-and-Drop library in pure SwiftUI.

Overview

SwiftUI Drag-and-Drop

Drag-and-drop is an intuitive gesture and can improve the UX of an app.

Chess Emoji Art Card Game To Do List
Chess Drag-And-Drop Demo Emoji Art Drag-And-Drop Demo Card Game Drag-And-Drop Demo To Do List Drag-And-Drop Demo
Documentation Documentation Documentation Documentation

Purpose of this library.

This library supports drag-and-drop in SwiftUI code. This is a replacement for the native onDrag / onDrop and their limitations.

Which Use Cases Does This Library Fit?

This library is a good fit if your use case falls into one or more of the following:

  • If you need or want to support drag-and-drop below iOS 16 (namely, iOS 13 or higher).
  • If you are drag-and-dropping non-NSObjects.
  • If you are not drag-and-dropping between apps (e.g., dragging URL from Safari to your app on an iPad).
  • If you are not (for whatever reason) enchanted with Apple's implementation.
  • If you like the way this library organizes drop logic on the draggable object rather than the drop-receiving object.

Getting Started.

The following steps will get your project compiling with a basic implementation of the library.

  1. Choose a type to conform to DropReceiver and conform the struct to it:
protocol DropReceiver {
    var dropArea: CGRect? { get set }
}

For example:

struct MyDropReceiver: DropReceiver {
    var dropArea: CGRect? = nil
}
  1. Conform your ViewModel to DropReceivableObservableObject & Add a variable in the ViewModel referencing the DropReceiver struct.
protocol DropReceivableObservableObject: ObservableObject {
    associatedtype DropReceivable: DropReceiver
    
    func setDropArea(_ dropArea: CGRect, on dropReceiver: DropReceivable)
}

For example:

class DragAndDropViewModel: DropReceivableObservableObject {
    typealias DropReceivable = MyDropReceiver
    
    var dropReceiver = MyDropReceiver()
        
    func setDropArea(_ dropArea: CGRect, on dropReceiver: DropReceivable) {
        dropReceiver.updateDropArea(with: dropArea)
    }
}
  1. Add the ViewModifier .dropArea(for:model:) to an element in your View which represents the DropReceiver struct. The for: should be an element of the type of the DropReceiver struct and the model: should be a reference to the DropReceivableObservableObject ViewModel.

For example:

struct MyDragAndDropView: View {
    @State var model = DragAndDropViewModel()
    
    var body: some View {
        VStack {
            Rectangle()
                .dropReceiver(for: model.dropReceiver, model: model)
        }
    }
}
  1. Add the ViewModifier .dragable() to any other element in the View. The code can now run and the View is draggable. It will show a blue shadow while dragging.

For example:

    var body: some View {
        VStack {
            Rectangle()
                .frame(width: 150, height: 150)
                .dropReceiver(for: model.dropReceiver, model: model)
                
            Spacer()
            
            Circle()
                .frame(width: 50, height: 50)
                .dragable()
        }
        .padding()
    }
  1. To see the dragged object and drop receiver interact, add these two function definitions to the View and assign them to .dragable(onDragged:onDropped:), respectively.
    func onDragged(position: CGPoint) -> DragState {
        if model.dropReceiver.getDropArea()!.contains(position) {
            return .accepted
        } else {
            return .rejected
        }
    }
    
    func onDropped(position: CGPoint) -> Bool {
        model.dropReceiver.getDropArea()!.contains(position)
    }

This code will allow a user to drag the object marked dragable and the shadow will now be green if the drop receiver is below the drag gesture or red if it is not.

In-Depth Examples of Implementation.

These examples are intended to showcase various implementations of drag-and-drop and are not intended to be full apps. Since drag-and-drop is a means of signaling user intent, these examples show various ways to capture that intent.

Emoji Art.

View the code. | Read the Documentation.

This example shows a single drop receiver (the canvas) and multiple drag-and-drop objects (the emoji on the palette & the emoji on the canvas).

To Do App.

View the code. | Read the Documentation.

A todo list where each list object can be dragged on top of a "Complete" box or a "Trash" box. The "Add New" button is draggable on top of the list to add a new object.

Chess Board.

View the code. | Read the Documentation.

This example shows how to implement drag-and-drop chess pieces on the chess board. The only movement rules are basic directional rules. The movement rules do not enforce check, checkmate, turn order, or board-wrapping (that is, a bishop on a3 can move to h3 as described here).

Card Game.

View the code. | Read the Documentation.

In this game, players can play a card in one of three playable areas: here, there, or yonder. Each card can be played in 1 or more of these areas.

Working with Non-Rectangular Drop Areas.

Read the tutorial.

This tutorial covers working with non-rectangular drop areas on a map or in a non-rectangular grid.

You might also like...
An elegant and flexible tweening library for iOS and tvOS.
An elegant and flexible tweening library for iOS and tvOS.

PMTween is an elegant and flexible tweening library for Objective-C, currently supporting the iOS and tvOS platforms. It offers sensible default funct

The Effects Library allows developers to create sophisticated and realistic particle systems such as snow, fire, rain, confetti, fireworks, and smoke with no or minimal effort.
The Effects Library allows developers to create sophisticated and realistic particle systems such as snow, fire, rain, confetti, fireworks, and smoke with no or minimal effort.

The Effects Library allows developers to create sophisticated and realistic particle systems such as snow, fire, rain, confetti, fireworks, and smoke with no or minimal effort.

An extensible iOS and OS X animation library, useful for physics-based interactions.
An extensible iOS and OS X animation library, useful for physics-based interactions.

Pop is an extensible animation engine for iOS, tvOS, and OS X. In addition to basic static animations, it supports spring and decay dynamic animations

A library of custom iOS View Controller Animations and Interactions.
A library of custom iOS View Controller Animations and Interactions.

RZTransitions is a library to help make iOS7 custom View Controller transitions slick and simple. Installation CocoaPods (Recommended) Add the followi

A powerful, elegant, and modular animation library for Swift.
A powerful, elegant, and modular animation library for Swift.

MotionMachine provides a modular, powerful, and generic platform for manipulating values, whether that be animating UI elements or interpolating prope

Swift animation library for iOS, tvOS and macOS.
Swift animation library for iOS, tvOS and macOS.

anim is an animation library written in Swift with a simple, declarative API in mind. // moves box to 100,100 with default settings anim { self.bo

LottieUI - A library developed to make Lottie easy to implement. It supports iOS and macOS

LottieUI It is a library developed to make Lottie easy to implement. It supports

SwiftUI iOS application allowing users to create profiles and meet and chat with people
SwiftUI iOS application allowing users to create profiles and meet and chat with people

FindR SwiftUI iOS application allowing users to create profiles and meet and cha

Releases(0.1.0)
Owner
Joel T. Huber
Joel T. Huber
SwiftUI-Text-Animation-Library - Text animation library for SwiftUI

⚠️ This repository is under construction. SwiftUI Text Animation Library Make yo

null 28 Jan 8, 2023
This library for animating text. Developed with SwiftUI. This library supports iOS/macOS.

AnimateText This library for animating text. Developed with SwiftUI. This library supports iOS/macOS. Screenshot AnimateText.mp4 Example https://fabul

jasu 123 Jan 2, 2023
Simple and light weight facebook login library for UIKit & SwiftUI

MjFbLogin Simple and light weight facebook login library which provides support for UIKit & SwiftUI Example To run the example project, clone the repo

Mohammad Jeeshan 2 Jul 3, 2022
Fortune spinning wheel library built using SwiftUI, supports dynamic content.

Fortune Wheel Fortune spinning wheel ?? library built using SwiftUI, supports dynamic content. Preview - Spin Wheel ⚙️ CocoaPods Installation FortuneW

Sameer Nawaz 51 Dec 23, 2022
Library for creating swipe actions for any SwiftUI View

SwipeActions Library for creating swipe actions for any SwiftUI View, similar to

Alexander Kraev 24 Dec 26, 2022
jasu 29 Dec 20, 2022
SwiftUI animated image view that works on iOS and layout just as SwiftUI.Image

SwiftUI.AnimatedImage SwiftUI animated image view that works on iOS and layout just as SwiftUI.Image Screen.Recording.2021-07-31.at.02.18.33.mov Insta

Marcin Krzyzanowski 50 Oct 14, 2022
Swiftui-animation-observer - Track SwiftUI animation progress and completion via callbacks

SwiftUI Animation Observer Track SwiftUI animation progress and completion via c

Gordan Glavaš 9 Nov 5, 2022
A Swift library to take the power of UIView.animateWithDuration(_:, animations:...) to a whole new level - layers, springs, chain-able animations and mixing view and layer animations together!

ver 2.0 NB! Breaking changes in 2.0 - due to a lot of requests EasyAnimation does NOT automatically install itself when imported. You need to enable i

Marin Todorov 3k Dec 27, 2022