# Gemini: 22 easing curves, one published release since 2019, and warnings allowed on the way out

> A Swift framework that animates a collection view while it scrolls, driven by a fluent method chain and completed by one call in the scroll delegate. Its newest published release is six years older than its most recent commit, its release process is a manual push to a package registry with warnings explicitly permitted, and the example project ships its dependency tree in the repository.

**shoheiyokoyama/Gemini** — GitHub describes it as Gemini is rich scroll based animation framework for iOS, written in Swift.. The repository metadata lists Swift as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

- Repository: https://github.com/shoheiyokoyama/Gemini
- Website: https://www.youtube.com/watch?v=bPtq5E6lKzw&utm_content=bufferfa3fd&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer
- Stars: 3,308 · Forks: 199
- Language: Swift
- License: MIT
- Published: 2026-08-13 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/shoheiyokoyama-gemini

## The last published release is six years older than the last commit

Two dates define the state of this project. The newest published release is 1.4.0, tagged in June 2019, preceded by 1.3.1 in October 2018 and 1.3.0 in May 2018. The most recent commit on the default branch is dated 2025-06-28. So the source has moved six years past the newest artefact, and the feature list still advertises support for version 5.0 of Swift, which is what that list would have said when the release was cut. Nobody is claiming the project is finished; the observation is simply that what you install from either dependency manager is a 2019 build, and anything newer has to come from the branch.

## The animation is driven from the scroll delegate method

The usage section is three steps and the third is the one that matters. You substitute the framework's collection view and cell classes for the UIKit ones, configure an animation with the chained interface, and then call the method that animates the visible cells from inside your scroll delegate callback. So the framework is not self-driving: it computes and applies, and you tell it when the scroll offset changed. There is one note attached to that, and it is the practical gotcha for anyone using this. If you want the animation applied as soon as a view appears rather than on the first scroll, you have to call the per-cell version from two other delegate callbacks, one for creating a cell and one for about to display it.

## Everything is configuration except the shadow, which needs a subclass

The design is a fluent chain, so an animation is a method call followed by property calls on the same expression:

```swift
collectionView.gemini
    .circleRotationAnimation()
    .radius(400)
    .rotateDirection(.clockwise)
```

You name an animation family, then set its parameters: a radius and a direction for the circular one, a degree for the cube, a degree and an effect for the rotation family, a scale and a direction for the scale animation. Then there are properties that apply across families, covering background colour, corner radius, transparency, an easing function and a shadow effect. Four of those five are plain chain calls. The shadow is not: the default is no shadow, and to get one you override the shadow view property in your own cell subclass and return the view you want used. So a shadow needs one mode chosen from a list of five and one subclass override, while everything else stays inside the chain.

## Twenty-two easing functions, grouped by curve family

The easing list is long and completely systematic: one linear function, then seven families of curves, each with an in, an out and an in-out variant. The families are named after the standard pen families, so you get quadratic, cubic, quartic, quintic, sine, exponential and circular, which is twenty-two names in total. That is a well-chosen set rather than an arbitrary one, and it is the kind of list where the absence of anything more exotic is itself a decision. One small thing: one entry in the list is indented with two spaces while every other line uses one, which suggests the list was assembled by hand and edited rather than generated.

## Five animation families, one of them borrowed from a phone app

The families are a cube, circular rotation, three-dimensional vector rotation, scale, and custom. The cube is described by comparison to a known app, and it has a single interesting parameter: a degree value, where ninety makes it move like a regular hexahedron. The three-dimensional family is the most carefully documented, because roll, pitch and yaw are mapped from three-dimensional vectors, and the figure explaining the axes cites the platform's own event handling guide for device motion data rather than inventing its own diagram. Each of the three rotation types takes an effect from a list of four and a degree. Scale simply grows or shrinks. Custom is the escape hatch, exposing around eleven properties at once, which is the most powerful thing in the framework and the easiest to get wrong.

## The feature list is a 2019 checklist that never got revisited

The checklist near the top has eleven ticked items and one line promising more. Rich animation with scrolling, ease of use, high customisability, several animation types, vertical and horizontal layouts, an easing function, support for version 5.0 of the language, the fluent interface, compatibility with two dependency managers, and an example project full of stock animations. Read today, two of those lines describe the world as it was when the last release was cut: the language version and, implicitly, the dependency managers. The checklist also says an easing function in the singular, while the section further down documents twenty-two, which suggests the list was written first and the library grew afterwards.

## The release is a manual push, and warnings are permitted

The build file has three targets and they explain the release history. One installs Ruby gems into a directory inside the repository. One lints the pod specification, and it passes a flag that allows warnings. One publishes, and it also passes a flag that allows warnings. So the path from source to a published version is a command somebody runs by hand, and both the check before it and the step itself tolerate a specification with warnings in it. That is consistent with a project where the last publish was in 2019: the process is intact and nobody has run it. It is also a hint about the specification itself, since a strict lint would have failed at some point.

## The example ships its dependency tree in the repository

The top level is short, and one entry should not be there: an Xcode project generated by the dependency manager, committed alongside the source. Inside the example directory the same pattern repeats at scale, with the project, the workspace, the source, the dependency manifest and its lockfile, a checked-in pods directory and a tests directory. So the entire dependency tree of the example is in version control, which means the repository carries code it did not write and cannot easily update. The remaining entries are conventional for the era: a Ruby gem file and its lockfile, a continuous integration configuration, a change log, the pod specification and the licence.

## Conclusion

This is a small, readable framework whose whole design is one subclass, one chain and one delegate call, which makes it a good thing to read even if you never link it. Two things to check before you do link it. The published release is six years behind the source, so anything published through the package managers is an old build and you would be vendoring from a branch. And the release path deliberately permits warnings, which tells you the pod has had warnings since before the last release. For an application still on a current toolchain, expect to be fixing the integration rather than adding it.

## FAQ

### What is the Gemini animation framework?

A scroll-based animation framework for iOS written in Swift, used through a collection view subclass and a cell subclass. It offers cube, circular rotation, three-dimensional roll, pitch and yaw, scale and fully custom animations, configured through a fluent method-chaining interface.

### How do I use Gemini in an iOS project?

Substitute its collection view and cell classes for the UIKit ones, configure the animation through the chained interface, and call the method that animates visible cells inside the scroll delegate callback. If you want animation before the first scroll, call the per-cell version from the two callbacks that create and display cells.

### Which iOS versions does Gemini support?

The feature list names support for version 5.0 of Swift and both vertical and horizontal flow layouts. The newest published release is 1.4.0 from June 2019, while the most recent commit is dated June 2025.

### How do I add a shadow effect with Gemini?

Override the shadow view property in a cell subclass and return your own view, then choose one of the five shadow modes. The default is no shadow, and this is the one feature that cannot be configured from the fluent chain alone.

### How is Gemini distributed?

Through either of the two dependency managers the feature list names, with a badge for each. The project's own release process pushes the pod to its public registry with warnings allowed, and the last such push produced the 2019 release.

## Sources

- [Official documentation](https://www.youtube.com/watch?v=bPtq5E6lKzw&utm_content=bufferfa3fd&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer)
- [Official README](https://github.com/shoheiyokoyama/Gemini#readme)
- [Project repository](https://github.com/shoheiyokoyama/Gemini)
- [Release notes](https://github.com/shoheiyokoyama/Gemini/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shoheiyokoyama-gemini
