dragology-swift
Unofficial portTell SwiftUI what an element can turn into, and let the drag work itself out.
Good drag interactions usually take a lot of careful code: hit regions, offsets, snapping, animation. Declarative dragging is a different way to build them, from a UIST 2026 paper. You draw your state, and list the states each element can be dragged to. The library does the geometry.
This package brings that idea to iOS. It's a from-scratch Swift port of the web library, with every drag operator, a SwiftUI host, and a gallery of more than thirty demos, most of them adapted from the original.
Permutation Lab, driven by real touches on an iPhone simulator.
A whole switch
This is all the code for a toggle. Nothing in it mentions touches, offsets, or animation.
func toggle(_ context: RenderContext<ToggleState>) -> Node<ToggleState> {
group {
rect(width: 120, height: 60, cornerRadius: 30)
.fill(context.state.isOn ? RGBA(hex: 0x22C55E) : RGBA(hex: 0xD1D5DB))
circle(radius: 26)
.id("knob")
.fill(.white)
.transform(.translate(context.state.isOn ? 90 : 30, 30))
.onDrag {
context.d.between([ToggleState(isOn: false), ToggleState(isOn: true)])
}
}
}
DraggableCanvas(state: $state, draggable: toggle)
How it works
When a drag starts, the library calls your own render function on each state you listed. Where the element lands in each of those renders tells it where the targets are. Those few positions are enough to build the whole interaction.
Drags are also composable. Small behaviors combine into bigger ones, so
d.closest(spots).withFloating().whenFar(free) reads as what it does: float over the nearest spot,
and move freely when far from all of them.
SwiftUI views can't be rendered speculatively or blended, so scenes are built from
Node, a plain-data tree that plays the part of SVG,
and drawn by a SwiftUI Canvas. The docs have the details.
Demos
These clips are from the demo app, which you can open in Xcode and run.
Get started
Add the package to your app. It needs iOS 17 or macOS 14.
.package(url: "https://github.com/jeslyvarghese/dragology-swift", from: "0.2.0")
Then follow Getting Started. The operator reference has the full vocabulary.
Status
This is an early release. A few things to know before you depend on it:
- It's been tested on the iOS simulator, but not yet on a physical iPhone, and performance hasn't been measured.
- A canvas claims every touch, so it can't sit inside a
ScrollViewyet. - Scene content isn't available to VoiceOver yet.
- SwiftUI views can't go inside a scene, and the original's debug views aren't ported.
The docs list these, along with how it differs from the web version.
Credits
The ideas here belong to Joshua Horowitz, Andrew Blinn, and Jeffrey Heer. If you use this in research, please cite their paper:
@inproceedings{horowitz2026declarative,
title = {Declarative Dragging},
author = {Horowitz, Joshua and Blinn, Andrew and Heer, Jeffrey},
booktitle = {Proceedings of the 39th Annual ACM Symposium on
User Interface Software and Technology (UIST '26)},
year = {2026}
}