RepoPilotOpen in app →

Ramotion/circle-menu

:octocat: ⭕️ CircleMenu is a simple, elegant UI menu with a circular layout and material design animations. Swift UI library made by @Ramotion

Mixed

Stale — last commit 4y ago

worst of 4 axes
Use as dependencyMixed

last commit was 4y ago; no tests detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 16 active contributors
  • Distributed ownership (top contributor 33% of recent commits)
  • MIT licensed
Show 3 more →
  • CI configured
  • Stale — last commit 4y ago
  • No test directory detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/ramotion/circle-menu?axis=fork)](https://repopilot.app/r/ramotion/circle-menu)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/ramotion/circle-menu on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: Ramotion/circle-menu

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Ramotion/circle-menu shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 4y ago

  • 16 active contributors
  • Distributed ownership (top contributor 33% of recent commits)
  • MIT licensed
  • CI configured
  • ⚠ Stale — last commit 4y ago
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live Ramotion/circle-menu repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/Ramotion/circle-menu.

What it runs against: a local clone of Ramotion/circle-menu — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in Ramotion/circle-menu | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 1428 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>Ramotion/circle-menu</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Ramotion/circle-menu. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/Ramotion/circle-menu.git
#   cd circle-menu
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of Ramotion/circle-menu and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Ramotion/circle-menu(\\.git)?\\b" \\
  && ok "origin remote is Ramotion/circle-menu" \\
  || miss "origin remote is not Ramotion/circle-menu (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "CircleMenuLib/CircleMenu.swift" \\
  && ok "CircleMenuLib/CircleMenu.swift" \\
  || miss "missing critical file: CircleMenuLib/CircleMenu.swift"
test -f "CircleMenuLib/CircleMenuButton/CircleMenuButton.swift" \\
  && ok "CircleMenuLib/CircleMenuButton/CircleMenuButton.swift" \\
  || miss "missing critical file: CircleMenuLib/CircleMenuButton/CircleMenuButton.swift"
test -f "CircleMenu/ViewController.swift" \\
  && ok "CircleMenu/ViewController.swift" \\
  || miss "missing critical file: CircleMenu/ViewController.swift"
test -f "CircleMenu/CircleMenu.h" \\
  && ok "CircleMenu/CircleMenu.h" \\
  || miss "missing critical file: CircleMenu/CircleMenu.h"
test -f "CircleMenuLib/CircleMenuLoader/CircleMenuLoader.swift" \\
  && ok "CircleMenuLib/CircleMenuLoader/CircleMenuLoader.swift" \\
  || miss "missing critical file: CircleMenuLib/CircleMenuLoader/CircleMenuLoader.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1428 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1398d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Ramotion/circle-menu"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

CircleMenu is a Swift UI library that renders a circular layout menu with material design animations. The core component is a UIButton subclass that expands/collapses child menu buttons arranged in a circle around a central button, with configurable animation duration and button-to-center distance. Single-component library: CircleMenu folder contains the main UIButton subclass with delegate pattern for button configuration. Example/demo app lives in CircleMenu/ root directory using Main.storyboard and AppDelegate.swift. Assets organized by type (AppIcon, Buttons) in Assets.xcassets. CocoaPods distribution via CircleMenu.podspec.

👥Who it's for

iOS app developers (Swift and Objective-C) who need to add elegant circular menu UI patterns to their applications without building custom animation and layout logic from scratch.

🌱Maturity & risk

Moderately mature. The project has CocoaPods and Carthage distribution, Travis CI configured, and is a polished UI library from Ramotion (a professional agency). However, the actual library code is minimal (~41KB Swift), suggesting focused scope rather than heavy development. No visible recent commit metadata provided, so activity level is unclear.

Low-to-moderate risk. The library has minimal dependencies (self-contained UI animation), but single-maintainer risk exists (no evidence of active community contributors). iOS 9.0+ requirement is aging (iOS 9 released 2015). Storyboard-based configuration adds tight coupling to Interface Builder, which can cause merge conflicts and portability issues.

Active areas of work

No specific activity data visible from file list. CHANGELOG.md and CONTRIBUTING.md exist, suggesting maintenance infrastructure is in place, but commit recency and open issues are not shown in provided metadata.

🚀Get running

git clone https://github.com/Ramotion/circle-menu.git
cd circle-menu
pod install  # if using CocoaPods
open CircleMenu.xcodeproj
# Or open CircleMenu.xcworkspace if pods were installed

Daily commands: Open CircleMenu.xcodeproj in Xcode 9.0.1+, select CircleMenu scheme, run on iOS 9.0+ simulator or device. Main.storyboard contains example implementation.

🗺️Map of the codebase

  • CircleMenuLib/CircleMenu.swift — Core menu controller that manages circular layout, animations, and button positioning—every contributor must understand the animation logic and delegate pattern here.
  • CircleMenuLib/CircleMenuButton/CircleMenuButton.swift — Individual menu button component with tap handling and state management—essential for understanding UI composition and interaction patterns.
  • CircleMenu/ViewController.swift — Demo integration showing how CircleMenu is instantiated and configured—reference implementation for contributors adding new features.
  • CircleMenu/CircleMenu.h — Objective-C bridging header that exposes the Swift library publicly—must be updated when adding new public APIs.
  • CircleMenuLib/CircleMenuLoader/CircleMenuLoader.swift — Loading animation component for async operations—shows animation patterns used throughout the library.
  • CircleMenu.podspec — CocoaPods specification defining versioning, dependencies, and Swift version constraints—critical for release and distribution.

🧩Components & responsibilities

  • CircleMenu (Swift, UIView, CABasicAnimation, UIViewController delegation) — Master controller managing menu state (open/closed), button collection, circular position calculation, animation orchestration, and delegate notification.
    • Failure mode: Menu fails to animate if button count is 0; animation stalls if CABasicAnimation has invalid duration or timingFunction.
  • CircleMenuButton (UIButton, CALayer, UIImage) — Lightweight button wrapper with visual styling (layer properties, shadow), tap target handling, and animation-ready layer setup.
    • Failure mode: Button unresponsive if target/action not set; visual glitches if layer frame is CGZero before animation.
  • CircleMenuLoader (UIView, CAShapeLayer, CABasicAnimation) — Animated loading indicator showing async operation progress; rotates circular path with CABasicAnimation.
    • Failure mode: Loader spins infinitely if not explicitly stopped; high CPU usage if rotation animation not removed from layer.
  • ViewController (Demo) (UIViewController, IBOutlet/IBAction, CircleMenuDelegate) — Orchestrates CircleMenu instantiation, configures button items, handles button action callbacks, and updates UI in response to menu events.
    • Failure mode: Menu not displayed if ViewController doesn't add CircleMenu.view to view hierarchy; actions crash if handlers not implemented.

🔀Data flow

  • User (tap)CircleMenuButton — Touch event bubbles from UIButton down to tap target action.

🛠️How to make changes

Add a new menu button with custom action

  1. Open CircleMenu/ViewController.swift and locate where button items are configured in viewDidLoad() (CircleMenu/ViewController.swift)
  2. Create a new CircleMenuButton instance with desired image and assign a target action for tap events (CircleMenu/ViewController.swift)
  3. Add the button to the CircleMenu by calling menu.addItem(button:) to automatically position it in the circular layout (CircleMenuLib/CircleMenu.swift)
  4. Implement the button's action handler method in ViewController to respond to tap events (CircleMenu/ViewController.swift)

Customize animation duration and easing

  1. Open CircleMenu.swift where CABasicAnimation objects are created for position, transform, and opacity changes (CircleMenuLib/CircleMenu.swift)
  2. Modify animation.duration property (typically 0.5–1.0 seconds) to speed up or slow down menu expansion/collapse (CircleMenuLib/CircleMenu.swift)
  3. Adjust animation.timingFunction (e.g., easeInEaseOut, easeOut) to control acceleration curves during animation (CircleMenuLib/CircleMenu.swift)

Add custom button styling or visual effects

  1. Examine CircleMenuButton.swift to understand button layer properties (backgroundColor, borderColor, shadow) (CircleMenuLib/CircleMenuButton/CircleMenuButton.swift)
  2. Extend CircleMenuButton with custom properties for color, border radius, or shadow effects in the init or setup method (CircleMenuLib/CircleMenuButton/CircleMenuButton.swift)
  3. Update button styling in ViewController.swift when instantiating CircleMenuButton objects with custom appearance values (CircleMenu/ViewController.swift)

Implement delegate callbacks for menu state changes

  1. Review CircleMenuDelegate protocol (referenced in CircleMenu.swift) to understand available callback methods (CircleMenuLib/CircleMenu.swift)
  2. Make ViewController conform to CircleMenuDelegate and implement didOpen/didClose or willOpen/willClose methods (CircleMenu/ViewController.swift)
  3. Assign the delegate: menu.delegate = self in ViewController to receive state change notifications from CircleMenu (CircleMenu/ViewController.swift)

🔧Why these technologies

  • Swift + UIKit — Native iOS framework for high-performance UI animations and touch event handling; CABasicAnimation provides smooth material design transitions.
  • Core Animation (CABasicAnimation) — Hardware-accelerated animation library essential for smooth 60fps circular menu expansion/collapse without frame drops.
  • CocoaPods + Swift Package Manager — Dual distribution support maximizes adoption across iOS projects using either package manager.

⚖️Trade-offs already made

  • Circular layout calculated programmatically rather than using Auto Layout

    • Why: Core Animation animations (transform, position) perform better than constraint-based layout updates; circular math is simpler than constraint equations.
    • Consequence: Manual frame/position management required; not responsive to runtime size changes, but gains 60fps animation performance.
  • Delegate pattern for menu state callbacks instead of reactive bindings (RxSwift/Combine)

    • Why: Lightweight, no external dependencies; simpler learning curve for developers unfamiliar with reactive paradigms.
    • Consequence: More boilerplate for consumers; no built-in chaining or transformation of menu events.
  • Single-file CircleMenu.swift for core logic instead of smaller modules

    • Why: Tighter cohesion for animation orchestration; reduces file fragmentation for a focused library.
    • Consequence: Single 500+ line file may become harder to navigate as features expand.

🚫Non-goals (don't propose these)

  • Does not provide drag-and-drop menu item reordering
  • Does not support nested or hierarchical submenus
  • Does not include dark mode theming or system appearance adaptation
  • Not compatible with SwiftUI (UIKit-only)
  • Does not provide localization support for button labels

🪤Traps & gotchas

Storyboard-heavy example means XIB/storyboard diffs during development can be noisy. @IBInspectable properties (buttonsCount, duration, distance) must be tuples of correct types or Interface Builder silently ignores them. Delegate method circleMenu(_:willDisplay:atIndex:) must be implemented to customize buttons—without it, menu buttons appear unconfigured. iOS 9.0+ requirement means modern Swift syntax features (if added) risk breaking compatibility.

🏗️Architecture

💡Concepts to learn

  • CABasicAnimation — CircleMenu's circular expand/collapse effect uses CABasicAnimation for smooth keyframe transitions; understanding timing functions and transform layers is essential to modifying animation behavior
  • UIButton Subclassing — CircleMenu extends UIButton to encapsulate layout logic and animation as a reusable component; subclassing patterns differ from composition and affect state management
  • Delegate Pattern — CircleMenu uses delegation (circleMenu(_:willDisplay:atIndex:)) to allow external configuration without exposing internal state; core iOS architecture pattern
  • IBInspectable Properties — Circular layout parameters (buttonsCount, distance, duration) are exposed as @IBInspectable to allow Storyboard/IB editing without code; requires strict type constraints
  • Trigonometric Layout (Polar Coordinates) — Menu buttons are positioned in a circle using sine/cosine to convert angle and distance to Cartesian coordinates; the math foundation of the circular arrangement
  • CocoaPods Pod Distribution — CircleMenu is packaged as a CocoaPod via podspec; understanding pod structure, version constraints, and subspecs is necessary for publishing and consuming
  • Ramotion/animated-tab-bar — Sibling Ramotion library providing material-design animated tab bar; similar animation patterns and IBInspectable property approach
  • Ramotion/paper-onboarding — Another Ramotion UI kit with similar delegate-driven configuration and CoreAnimation usage
  • nicklockwood/iCarousel — Alternative circular/carousel layout library for iOS; different approach (view container vs. button subclass) solving overlapping UI layout problem
  • realm/realm-swift — Common dependency in Ramotion projects for persistent data in demo apps; not currently used here but ecosystem context
  • CocoaPods/CocoaPods — Dependency manager used for distribution; CircleMenu.podspec defines how this library is packaged and installed

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for CircleMenuButton.swift

CircleMenuTests/CircleMenuTests.swift exists but appears minimal. CircleMenuLib/CircleMenuButton/CircleMenuButton.swift is a core component handling button animations and states, but lacks dedicated test coverage. This would improve reliability for contributors modifying button behavior, animation timing, or state management.

  • [ ] Create CircleMenuTests/CircleMenuButtonTests.swift with test cases for button initialization, layout calculations, and animation states
  • [ ] Add tests for tap interactions and state transitions (active/inactive)
  • [ ] Test animation duration and timing parameters match expected values
  • [ ] Verify button positioning calculations in circular layout are correct

Add GitHub Actions CI workflow to replace Travis CI

.travis.yml indicates the project uses Travis CI, which has been deprecated. GitHub Actions is the modern standard. Creating a workflow file would ensure automated testing on pull requests, improve contributor confidence, and provide faster feedback loops. No GitHub Actions workflow exists in the repo structure.

  • [ ] Create .github/workflows/swift-ci.yml with Swift build and test jobs
  • [ ] Configure matrix testing for multiple iOS/Swift versions from .swift-version specification
  • [ ] Run xcodebuild test for CircleMenuTests target on pull requests
  • [ ] Add job to validate that .podspec passes pod lib lint for CocoaPods compatibility

Add integration tests for CircleMenu.swift view controller interactions

CircleMenuLib/CircleMenu.swift is the main menu view component but has no visible integration tests. The ViewController.swift demo file shows real usage patterns (menu opening/closing, button callbacks) that should be tested. This ensures the menu lifecycle and delegate patterns work correctly across updates.

  • [ ] Create CircleMenuTests/CircleMenuIntegrationTests.swift for menu show/hide animations
  • [ ] Test CircleMenu delegate callbacks fire correctly when menu items are tapped
  • [ ] Verify menu state (open/closed) is managed properly through multiple interaction cycles
  • [ ] Test configuration parameters (radius, angle, duration) are applied to button positioning and animations

🌿Good first issues

  • Add unit tests for button layout math: CircleMenu calculates positions in a circle using trigonometry—create XCTest cases in a new CircleMenuTests/ folder to verify button positions at various buttonsCount and distance values don't overlap.
  • Document programmatic initialization in README: the README shows only storyboard usage; add a 'Programmatic Setup' section with complete code example showing CGRect, normalIcon, selectedIcon parameters from the README snippet.
  • Extract animation constants to a public struct: hardcoded animation durations/curves exist in the button expand/collapse logic—refactor to a configurable AnimationConfig struct exposed as a public property, with docs.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 4534c0d — Merge pull request #64 from nzufelt/patch-1 (igork-ramotion)
  • b24752e — Fix typo! (nzufelt)
  • 22ef289 — Update README.md (RamotionDev)
  • 1428534 — fix problems with running on simulator (issue #61) (igork-ramotion)
  • 3ee0a8a — add SPM config and Ramotion application icon set (igork-ramotion)
  • 0f35c65 — Update README.md (RamotionDev)
  • c578516 — bump version (0ber)
  • 1d00b25 — converted to swift 5 (0ber)
  • 37940a6 — Update README.md (RamotionDev)
  • 739c698 — Add files via upload (RamotionDev)

🔒Security observations

This is a UI library (CircleMenu) for iOS with a relatively low attack surface. No critical vulnerabilities were identified from the file structure analysis. The codebase appears to be a pure UI component library without database access, network requests, or authentication logic visible in the file listing. Primary recommendations focus on dependency management, maintaining updated Swift/dependencies, and establishing security best practices documentation. The main security concerns are operational rather than inherent to the code itself.

  • Low · Missing dependency vulnerability scanning — Package.swift. The Package.swift file content was not provided for analysis. Swift Package Manager dependencies should be audited for known vulnerabilities using tools like Swift Audit. Fix: Regularly run swift audit or use dependency scanning tools to identify vulnerable packages. Pin dependency versions and review CHANGELOG.md for security updates.
  • Low · Outdated Swift version reference — .swift-version. The .swift-version file exists but its content was not provided. This may indicate an older Swift version that could have unpatched security vulnerabilities. Fix: Ensure the project uses the latest stable Swift version. Update .swift-version to the current LTS or latest Swift release and rebuild/test the application.
  • Low · Missing security headers in documentation — CONTRIBUTING.md, README.md. No evidence of security documentation, vulnerability disclosure policy, or security guidelines in CONTRIBUTING.md or README.md. Fix: Add a SECURITY.md file with vulnerability reporting instructions and a security policy. Include security best practices in CONTRIBUTING.md.
  • Low · Build configuration not reviewed — .travis.yml. Travis CI configuration (.travis.yml) present but content not provided for review. This could contain exposed environment variables or insecure build practices. Fix: Review .travis.yml to ensure: no hardcoded secrets, secure environment variable handling, encrypted credentials only, and up-to-date dependency versions in CI/CD pipeline.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · Ramotion/circle-menu — RepoPilot