RepoPilotOpen in app →

scenee/FloatingPanel

A clean and easy-to-use floating panel UI component for iOS

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

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.

  • Last commit 3mo ago
  • 5 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Single-maintainer risk — top contributor 95% of recent commits

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 "Healthy" badge

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

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/scenee/floatingpanel)](https://repopilot.app/r/scenee/floatingpanel)

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/scenee/floatingpanel on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: scenee/FloatingPanel

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/scenee/FloatingPanel 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

GO — Healthy across all four use cases

  • Last commit 3mo ago
  • 5 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Single-maintainer risk — top contributor 95% of recent commits

<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 scenee/FloatingPanel repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/scenee/FloatingPanel.

What it runs against: a local clone of scenee/FloatingPanel — 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 scenee/FloatingPanel | 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 ≤ 115 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>scenee/FloatingPanel</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of scenee/FloatingPanel. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/scenee/FloatingPanel.git
#   cd FloatingPanel
#
# 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 scenee/FloatingPanel and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "scenee/FloatingPanel(\\.git)?\\b" \\
  && ok "origin remote is scenee/FloatingPanel" \\
  || miss "origin remote is not scenee/FloatingPanel (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 "Sources/FloatingPanel.swift" \\
  && ok "Sources/FloatingPanel.swift" \\
  || miss "missing critical file: Sources/FloatingPanel.swift"
test -f "Sources/FloatingPanelController.swift" \\
  && ok "Sources/FloatingPanelController.swift" \\
  || miss "missing critical file: Sources/FloatingPanelController.swift"
test -f "Sources/FloatingPanelLayout.swift" \\
  && ok "Sources/FloatingPanelLayout.swift" \\
  || miss "missing critical file: Sources/FloatingPanelLayout.swift"
test -f "Sources/Core/State.swift" \\
  && ok "Sources/Core/State.swift" \\
  || miss "missing critical file: Sources/Core/State.swift"
test -f "Documentation/FloatingPanel API Guide.md" \\
  && ok "Documentation/FloatingPanel API Guide.md" \\
  || miss "missing critical file: Documentation/FloatingPanel API Guide.md"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 115 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~85d)"
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/scenee/FloatingPanel"
  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

FloatingPanel is a production-ready iOS UI component that displays a draggable, resizable panel overlaid on the main content—similar to Apple Maps, Stocks, and Shortcuts apps. It handles fluid spring animations, scroll view tracking, multi-position support (top, left, bottom, right), magnetic anchoring, and removal gestures without manual Auto Layout or gesture handling. Monorepo structure: core FloatingPanel framework source under Sources/, two major UIKit examples (Examples/Maps and Examples/Stocks), SwiftUI example (Examples/Maps-SwiftUI), and auxiliary sample projects. BuildTools/ contains Swift formatting plugins. Documentation/ holds API guides and migration notes. Single package.swift entry point for SPM.

👥Who it's for

iOS developers (UIKit and SwiftUI) building apps with supplementary content panels—such as search results, details panels, or bottom sheets—who want Apple-quality animations and interaction without building gesture handling and layout logic from scratch.

🌱Maturity & risk

Actively maintained and production-ready. The repo has a mature API (v3.2.1), comprehensive examples (Maps, Stocks, SwiftUI variants), CI/CD via GitHub Actions (.github/workflows/ci.yml), detailed migration guides (2.0 Migration Guide), and API documentation on Swift Package Index. Recent activity evident from multiple example projects and SwiftUI support.

Low risk overall. Single maintainer (@scenee based on repo name) is a typical pattern for solid open-source libraries. No heavy external dependencies visible (400K+ lines of Swift in core, minimal Ruby/Obj-C wrapper code). Breaking changes are documented in CHANGELOG.md and migration guides, reducing upgrade friction. Objective-C compatibility and broad iOS version support (12.0+) indicate stability.

Active areas of work

Active SwiftUI expansion: Examples/Maps-SwiftUI has dedicated components (FloatingPanelContentView.swift, HostingCell.swift, SearchPanelPhoneDelegate.swift) showing modern patterns. CI via .github/workflows/ci.yml is configured. The project maintains backward compatibility while adding SwiftUI Representable wrappers and new API docs on Swift Package Index.

🚀Get running

git clone https://github.com/scenee/FloatingPanel.git && cd FloatingPanel && open Examples/Maps/Maps.xcodeproj (UIKit) or open Examples/Maps-SwiftUI/Maps-SwiftUI.xcodeproj (SwiftUI). For SPM integration, use Xcode → File → Add Packages → https://github.com/scenee/FloatingPanel.git.

Daily commands: UIKit: open Examples/Maps/Maps.xcodeproj && select Maps scheme, build and run. SwiftUI: open Examples/Maps-SwiftUI/Maps-SwiftUI.xcodeproj && select Maps scheme, build and run. Both target iOS 12.0+ simulators and devices.

🗺️Map of the codebase

  • Sources/FloatingPanel.swift — Core FloatingPanel class — the main UI component that orchestrates panel state, animations, and gesture handling; every feature depends on this.
  • Sources/FloatingPanelController.swift — UIViewController wrapper managing panel lifecycle, layout, and delegate callbacks; essential entry point for UIKit users.
  • Sources/FloatingPanelLayout.swift — Protocol defining panel positioning, sizing, and layout behavior; required for customizing panel appearance and responsiveness.
  • Sources/Core/State.swift — Defines panel state machine (collapsed, tip, half, full) and transitions; fundamental to understanding panel behavior.
  • Documentation/FloatingPanel API Guide.md — Primary reference documentation covering configuration, delegates, and common patterns; required reading for integration.
  • Examples/Maps/Maps/MainViewController.swift — Real-world UIKit usage example showing panel setup, delegate implementation, and interaction patterns.
  • Examples/Maps-SwiftUI/Maps/ContentView.swift — Real-world SwiftUI usage example demonstrating FloatingPanelRepresentable integration and state management.

🧩Components & responsibilities

  • FloatingPanelController / FloatingPanel (UIViewController, SwiftUI View, State machine) — Top-level coordinator; owns state, layout, gesture recognizers, and delegate callbacks.
    • Failure mode: Incorrect state transitions or missed gestures due to conflicting responders or layout misconfiguration.
  • State Machine (State.swift) (Swift enum, computed properties) — Tracks current position (collapsed, tip, half, full) and validates transitions; emits animations.
    • Failure mode: Ambiguous state or invalid transitions can cause animations to stall or skip frames.
  • Layout Engine (FloatingPanelLayout protocol + implementations) (CGRect, NSLayoutConstraint, adaptive layout) — Computes insets, frame bounds, and positioning anchors for each state; adapts to screen size/rotation.
    • Failure mode: Incorrect frame calculations cause off-screen rendering, overlaps, or broken landscape/iPad support.
  • Gesture Handler (GestureHandling.swift) (UIPanGestureRecognizer, CGPoint, CGVector) — Intercepts pan gestures, calculates velocity/translation, and selects target state.
    • Failure mode: Missed gestures or miscomputed velocity can make dragging feel unresponsive or snap to wrong state.
  • Animation Engine (Animation.swift) (CABasicAnimation, UIView.animate, timing curves) — Applies spring or timing-curve animations to transition between states.
    • Failure mode: Animation timing mismatches can cause visual jank, incomplete transitions, or imperceptible animations.

🔀Data flow

  • User Gesture (pan)Gesture Handler — UIPanGestureRecognizer fires with translation and velocity
  • Gesture HandlerState Machine — Velocity/translation determine target state (e.g., half

🛠️How to make changes

Create a Custom Panel Layout

  1. Create a new class conforming to FloatingPanelLayout protocol (Sources/FloatingPanelLayout.swift)
  2. Implement required methods: insetFor(position:), widthForCompactAxis(maximumWidth:), and positioning anchors (MyCustomLayout.swift)
  3. Pass your layout to FloatingPanelController.layout property during initialization (Examples/Maps/Maps/MainViewController.swift)

Add a Panel Delegate to Respond to State Changes

  1. Create a class conforming to FloatingPanelControllerDelegate (Sources/FloatingPanelController.swift)
  2. Implement delegate methods like floatingPanelDidChangeState(:) and floatingPanelWillBeginDragging(:) (Examples/Maps/Maps/MainViewController.swift)
  3. Assign your delegate to the controller's delegate property (Examples/Maps/Maps/MainViewController.swift)

Integrate FloatingPanel into SwiftUI

  1. Use FloatingPanel view directly or wrap with FloatingPanelRepresentable for UIKit content (Examples/Maps-SwiftUI/Maps/ContentView.swift)
  2. Pass content as a closure to the FloatingPanel initializer (Examples/Maps-SwiftUI/Maps/FloatingPanelContentView.swift)
  3. Customize appearance with SurfaceAppearance and position modifiers (Examples/Maps-SwiftUI/Maps/SurfaceAppearance+phone.swift)

Configure Multiple Floating Panels

  1. Create multiple FloatingPanelController instances with distinct identifiers (Examples/Samples/Sources/ContentViewControllers/MultiPanelController.swift)
  2. Set unique z-index or positioning via layout for each panel to avoid conflicts (Sources/FloatingPanelLayout.swift)
  3. Manage state separately for each panel in your view controller or SwiftUI state (Examples/Samples/Sources/ContentViewControllers/MultiPanelController.swift)

🔧Why these technologies

  • Swift + UIKit/SwiftUI dual support — Maximizes compatibility across codebases (legacy UIKit and modern SwiftUI); provides gradual migration path.
  • State machine (collapsed/tip/half/full) — Explicit, predictable state transitions reduce bugs; makes gesture logic and animations deterministic.
  • Layout protocol abstraction — Decouples UI positioning from core logic; enables infinite customization (adaptive layouts, breakpoints) without modifying core.
  • Pan gesture + spring animation — Mirrors native iOS feel (Maps, Shortcuts, Stocks); provides smooth, responsive, physics-based interaction.

⚖️Trade-offs already made

  • Strict state machine with discrete positions rather than continuous free-form dragging

    • Why: Simplifies animation, layout, and delegate callbacks; matches Apple's design patterns.
    • Consequence: Less flexibility for non-standard layouts; position snap-to-grid may feel constraining for some use cases.
  • Layout protocol + position constraints over raw frame manipulation

    • Why: Enables adaptive layout (iPad vs. iPhone, landscape vs. portrait) without per-case coding.
    • Consequence: Steeper learning curve for custom layouts; users must understand inset, position, and anchor APIs.
  • Delegate pattern + closure-based callbacks over reactive/Combine streams

    • Why: Backward compatible with UIKit patterns; lower barrier to entry.
    • Consequence: Misses modern declarative reactive patterns; SwiftUI integration requires wrapper layer.

🚫Non-goals (don't propose these)

  • Does not handle authentication or authorization
  • Not a navigation framework — panels are overlays, not page replacements
  • Does not manage keyboard input/dismissal automatically — users must integrate manually
  • Not optimized for non-iOS platforms (tvOS, watchOS, macOS not primary targets)
  • Does not provide built-in accessibility features beyond basic VoiceOver support

🪤Traps & gotchas

SwiftUI vs UIKit API differences: FloatingPanel has two separate API layers—ensure you're using the correct one for your framework. Scroll view tracking requires explicit FloatingPanelControllerDelegate implementation; missing it breaks drag-to-dismiss. Anchor positions (full, half, tip) must match your content height or layout breaks in landscape. No explicit test directory visible in file list—verify test location in actual repo before adding tests.

🏗️Architecture

💡Concepts to learn

  • Numeric Spring Animation — FloatingPanel's signature fluid drag behavior relies on numeric spring physics (not CABasicAnimation bezier curves)—understanding spring damping and stiffness is key to customizing panel feel
  • UIScrollViewDelegate Tracking — FloatingPanel intercepts scroll view content offset changes to coordinate panel position with nested scrollable content—critical for seamless drag-to-expand/collapse interactions
  • Gesture Recognizer Interaction — Panel dismissal and repositioning rely on custom UIPanGestureRecognizer handling without conflicting with scroll view gestures—a non-trivial coordination problem FloatingPanel solves
  • Trait-Based Layout Adaptation — FloatingPanel adjusts panel position and size based on device orientation and size class—the architecture supports all trait environments without manual orientation observers
  • SwiftUI Representable Bridge Pattern — Examples/Maps-SwiftUI shows UIViewControllerRepresentable and UIViewRepresentable wrappers—essential for integrating legacy UIKit components into modern SwiftUI apps
  • Modal Presentation Controller Customization — FloatingPanel can be presented modally via UIPresentationController—requires custom transition animation and dismissal handling to preserve the spring behavior
  • Magnetic Anchoring / Snap-to-Position — Panel snaps to predefined anchor positions (full, half, tip, custom) when released—the algorithm determines which anchor is nearest based on velocity and distance, similar to Apple Maps behavior
  • jrendel/SwiftKeychainWrapper — Frequently paired with FloatingPanel in iOS apps needing secure credential storage in presented panels
  • realm/realm-swift — Common data source for FloatingPanel-based detail/search panels in iOS apps (e.g., search results in Maps example)
  • danielsaidi/KeyboardKit — Handles keyboard interaction in FloatingPanel content (e.g., search bars in Maps-SwiftUI example avoid keyboard overlap)
  • airbnb/lottie-ios — Used for custom animations and transitions within FloatingPanel content areas
  • pointfreeco/swift-composable-architecture — Alternative state management for complex FloatingPanel interactions in SwiftUI (complementary to environment-based approach shown in examples)

🪄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 SwiftUI integration tests for FloatingPanel

The repo has SwiftUI support (Maps-SwiftUI example and SwiftUI API Guide exist), but there's no dedicated test suite for SwiftUI-specific behavior. The Examples/Maps-SwiftUI contains production code but likely no automated tests for FloatingPanel's SwiftUI bindings, state management, and lifecycle integration. This is critical for ensuring SwiftUI support doesn't regress.

  • [ ] Create Tests/FloatingPanelSwiftUITests directory with test targets in Package.swift
  • [ ] Add tests for FloatingPanel state transitions (collapsed, half, full positions) in SwiftUI context
  • [ ] Add tests for gesture handling and drag interactions in SwiftUI (test both UIViewRepresentable and native SwiftUI APIs)
  • [ ] Test keyboard interaction with SwiftUI content (reference: UIHostingController+ignoreKeyboard.swift shows this is a known concern)
  • [ ] Integrate tests into .github/workflows/ci.yml to run on PRs

Add iOS 13/14 compatibility test matrix to CI workflow

The .spi.yml and .swift-format exist but ci.yml likely only tests a single iOS version. Given this is a mature UI component used in production Apple apps, contributors should verify compatibility across iOS 13+ (especially with SwiftUI being iOS 13+). No matrix testing visible in the partial file structure.

  • [ ] Expand .github/workflows/ci.yml to include matrix testing across iOS 13, 14, 15, 16, 17+
  • [ ] Add separate build jobs for UIKit and SwiftUI examples across iOS versions
  • [ ] Document minimum supported iOS version in README if not already present
  • [ ] Add a compatibility matrix section to Documentation/FloatingPanel API Guide.md

Create missing unit tests for gesture recognition and panel positioning logic

The repo has two full example apps (Maps and Samples) indicating complex gesture and positioning logic, but the file structure shows no Tests directory. Core features like gesture handling, smooth transitions, and position calculations need unit test coverage to prevent regressions when contributors modify core behavior.

  • [ ] Create Tests directory with FloatingPanelTests target in Package.swift
  • [ ] Add unit tests for position calculation logic (collapsed/half/full state transitions)
  • [ ] Add tests for gesture recognizer behavior and drag velocity handling
  • [ ] Add tests for layout calculations across different device orientations and safe areas
  • [ ] Add tests for the SearchPanelPhoneDelegate pattern (shown in Examples/Maps-SwiftUI) to verify delegate callbacks
  • [ ] Integrate test execution into ci.yml

🌿Good first issues

  • Add unit tests for Examples/Maps-SwiftUI/Maps/SearchPanelPhoneDelegate.swift—currently no visible test coverage for SwiftUI delegate patterns
  • Document the HostingCell.swift pattern in a new 'SwiftUI Integration Patterns' guide under Documentation/—helps future contributors understand UITableView + SwiftUI + FloatingPanel layering
  • Add landscape orientation tests/examples for Examples/Maps-SwiftUI—documentation shows landscape gif but SwiftUI example may lack explicit landscape trait handling

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 7efcc76 — ci: update Xcode 26.0.1 to 26.2 (scenee)
  • feaa40d — Fix stale binding value reverting panel state during SwiftUI re-renders (scenee)
  • 658be4d — Update MainView in SamplesSwiftUI for #680 (scenee)
  • 6da6b69 — Add CoordinatorProxyTests (scenee)
  • e64aafe — Fix panel interactivity broken by floatingPanelState(_:) with delegate callbacks (#680) (scenee)
  • ee2c6fe — Version 3.2.1 (scenee)
  • 6a343c8 — Perform view updates during scroll tracking (#679) (sgade)
  • cd135b3 — Fix scroll offset reset due to floating-point precision errors (#677) (scenee)
  • 9e8fd34 — ci: fix 'swiftpm' job (scenee)
  • 612082c — Remove badges from README (scenee)

🔒Security observations

FloatingPanel is a UI library with minimal security risks. No critical vulnerabilities detected. The codebase does not contain SQL injection vectors, XSS vulnerabilities, hardcoded secrets, or exposed credentials. Primary concerns are standard best practices around dependency management and example code isolation. The project follows a clean structure with example applications properly separated. Recommend implementing dependency pinning in Package.resolved and validating example code doesn't leak sensitive information.

  • Low · Missing Swift Package Manifest Validation — BuildTools/Package.swift, BuildTools/Package@swift-5.9.swift. The repository contains multiple Package.swift files (Package.swift and Package@swift-5.9.swift) in BuildTools. While this is intentional for Swift version compatibility, there is no visible dependency pinning or lock file (Package.resolved) in the provided file structure, which could lead to unexpected dependency updates. Fix: Ensure Package.resolved files are committed to version control to lock dependency versions and prevent supply chain attacks through unexpected updates.
  • Low · Potential Insecure Example App Data Handling — Examples/Maps/Maps/, Examples/Maps-SwiftUI/Maps/, Examples/Samples/Sources/. Example applications in Examples/ directory (Maps, Samples) may contain hardcoded URLs, API endpoints, or test data that could inadvertently expose sensitive information if examples are used as templates for production code. Fix: Review example code to ensure no production credentials, API keys, or sensitive endpoints are hardcoded. Use environment variables or configuration files for sensitive data in examples.
  • Low · GitHub Workflows Without Explicit Security Pinning — .github/workflows/ci.yml. The CI/CD workflow file (.github/workflows/ci.yml) is present but content is not provided. GitHub Actions should use specific action versions rather than floating tags (e.g., 'v1' instead of 'latest') to prevent supply chain attacks. Fix: Ensure all GitHub Actions use specific version pinning (e.g., actions/checkout@v4.1.0 instead of @v4) and regularly audit action dependencies for vulnerabilities.

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.

Healthy signals · scenee/FloatingPanel — RepoPilot