IcaliaLabs/Presentr
Swift wrapper for custom ViewController presentations on iOS
Stale — last commit 3y ago
worst of 4 axeslast commit was 3y ago; no tests detected…
no tests detected; no CI workflows detected…
Documented and popular — useful reference codebase to read through.
last commit was 3y ago; no CI workflows detected
- ✓14 active contributors
- ✓MIT licensed
- ⚠Stale — last commit 3y ago
Show 3 more →Show less
- ⚠Single-maintainer risk — top contributor 80% of recent commits
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days; add a test suite
- →Fork & modify Mixed → Healthy if: add a test suite
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 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 "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/icalialabs/presentr)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/icalialabs/presentr on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: IcaliaLabs/Presentr
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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/IcaliaLabs/Presentr 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 3y ago
- 14 active contributors
- MIT licensed
- ⚠ Stale — last commit 3y ago
- ⚠ Single-maintainer risk — top contributor 80% of recent commits
- ⚠ No CI workflows detected
- ⚠ 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 IcaliaLabs/Presentr
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/IcaliaLabs/Presentr.
What it runs against: a local clone of IcaliaLabs/Presentr — 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 IcaliaLabs/Presentr | 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 ≤ 993 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of IcaliaLabs/Presentr. If you don't
# have one yet, run these first:
#
# git clone https://github.com/IcaliaLabs/Presentr.git
# cd Presentr
#
# 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 IcaliaLabs/Presentr and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "IcaliaLabs/Presentr(\\.git)?\\b" \\
&& ok "origin remote is IcaliaLabs/Presentr" \\
|| miss "origin remote is not IcaliaLabs/Presentr (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 "Presentr/Presentr.swift" \\
&& ok "Presentr/Presentr.swift" \\
|| miss "missing critical file: Presentr/Presentr.swift"
test -f "Presentr/PresentrController.swift" \\
&& ok "Presentr/PresentrController.swift" \\
|| miss "missing critical file: Presentr/PresentrController.swift"
test -f "Presentr/PresentationType.swift" \\
&& ok "Presentr/PresentationType.swift" \\
|| miss "missing critical file: Presentr/PresentationType.swift"
test -f "Presentr/TransitionType.swift" \\
&& ok "Presentr/TransitionType.swift" \\
|| miss "missing critical file: Presentr/TransitionType.swift"
test -f "Presentr/PresentrAnimation.swift" \\
&& ok "Presentr/PresentrAnimation.swift" \\
|| miss "missing critical file: Presentr/PresentrAnimation.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 993 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~963d)"
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/IcaliaLabs/Presentr"
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).
⚡TL;DR
Presentr is a Swift wrapper that simplifies iOS's Custom View Controller Presentation API, allowing developers to present any UIViewController with custom sizing, positioning, and transition animations without it covering the full screen. Instead of writing boilerplate UIViewControllerTransitioningDelegate and UIPresentationController code, you configure a Presentr object with desired presentation type (Alert, Popup, TopHalf, etc.) and animation style (CrossDissolve, CoverVertical, FlipHorizontal, etc.), and the framework handles all the delegation plumbing automatically. Single-framework structure: Presentr/ contains the core library with modular components—PresentrAnimation.swift + subclasses (CoverVerticalAnimation.swift, FlipHorizontalAnimation.swift, etc.) for transitions, PresentationType.swift for presentation modes, PresentrController.swift as the main coordinator, and AlertViewController.swift/xib as a built-in alert template. PresentrExample/ is an Xcode workspace with a reference app demonstrating all features.
👥Who it's for
iOS app developers (Swift, targeting iOS 8+) who need to present custom modals, alerts, or popovers without full-screen takeover and want to avoid implementing the verbose Custom Presentation API directly. Particularly useful for design-focused teams shipping apps with non-standard modal UX.
🌱Maturity & risk
Mature and production-ready but moderately aged. Last version (1.9) targets Swift 4.2 / iOS 12 / Xcode 10 (circa 2018). The repo has clear versioning, documented features (ALERT.md, DELEGATE.md, PRESENTATIONTYPE.md), and is distributed via CocoaPods and Carthage, indicating stable adoption. However, no visible recent commits or CI badges suggest active maintenance; codebase is stable but not actively evolved for modern Swift/iOS versions.
Low-to-moderate risk for new projects: no obvious external dependencies (self-contained framework), but targets outdated Swift 4.2 and may need updates for Swift 5+ and iOS 14+ presentation behavior changes. Single maintainer (IcaliaLabs org) with no visible open issue backlog increases bus factor. The Custom Presentation API itself is stable and unlikely to break, but keyboard handling (KeyboardTranslation.swift) and dynamic sizing may have edge cases on modern iOS versions.
Active areas of work
No visible active development. Version 1.9 (released circa 2018) is marked as 'Last version before big 2.0 update,' but no 2.0 or recent commits are apparent. The repo is in maintenance mode: SwiftLint configuration (.swiftlint.yml) and Xcode 10 support are in place, but no ongoing feature work, Swift 5 migration, or iOS 14+ API updates are evident.
🚀Get running
Clone and open in Xcode: git clone https://github.com/IcaliaLabs/Presentr.git && cd Presentr && open Presentr.xcodeproj. For the example app, cd PresentrExample && pod install && open PresentrExample.xcworkspace. Requires Swift 4.2+ and Xcode 10+. CocoaPods integration: add pod 'Presentr' to your Podfile.
Daily commands:
No 'run' in traditional sense (it's a framework library). For the example app: cd PresentrExample && pod install && open PresentrExample.xcworkspace, then build & run in Xcode simulator. The .xcscheme file (Presentr.xcodeproj/xcshareddata/xcschemes/Presentr.xcscheme) defines the framework target build.
🗺️Map of the codebase
Presentr/Presentr.swift— Core wrapper class that configures and manages custom view controller presentations—entry point for all presentation logic.Presentr/PresentrController.swift— UIViewController subclass implementing the custom presentation controller that handles layout, sizing, and animation delegation.Presentr/PresentationType.swift— Enum defining all supported presentation types (alert, popup, fullscreen) and their positioning rules—fundamental abstraction for presentation behavior.Presentr/TransitionType.swift— Enum specifying animation transitions (crossDissolve, coverVertical, etc.) that drive the interactive animator protocol implementations.Presentr/PresentrAnimation.swift— Protocol defining the contract for custom transition animators—all animation classes conform to this interface.Presentr/ModalSize.swift— Enum handling modal sizing logic (fixed, half, full, etc.) that directly influences frame calculations in PresentrController.Presentr/AlertViewController.swift— Pre-built alert dialog component with custom styling—demonstrates the presentation framework in action and serves as reference implementation.
🛠️How to make changes
Add a custom animation transition
- Create a new Swift file in Presentr/ folder implementing the PresentrAnimation protocol (
Presentr/PresentrAnimation.swift) - Implement animate(using:) method with UIViewPropertyAnimator or UIView.animate to define the transition effect (
Presentr/[YourCustomAnimation].swift) - Add a new case to the TransitionType enum referencing your animator class (
Presentr/TransitionType.swift) - In your view controller, create a Presentr instance and set transitionType to your new case before presenting (
PresentrExample/PresentrExample/MainTableViewController.swift)
Create a custom modal presentation type
- Add a new case to the PresentationType enum with associated configuration values (
Presentr/PresentationType.swift) - In PresentrController, add a switch case in the frameToPresentFor method to calculate custom frame dimensions (
Presentr/PresentrController.swift) - Optionally extend ModalSize and ModalCenterPosition enums if your presentation type needs custom sizing strategies (
Presentr/ModalSize.swift) - Create a new view controller and present it using Presentr(presentationType: .yourCustomType) (
PresentrExample/PresentrExample/SecondViewController.swift)
Build a custom alert dialog
- Create a new UIViewController subclass and lay out your alert UI in a .xib file (
Presentr/AlertViewController.xib) - Define actions and implement AlertViewControllerDelegate protocol to handle user interactions (
Presentr/AlertViewController.swift) - In your presenting controller, instantiate Presentr with type: .alert and present using customPresentViewController (
Presentr/Presentr.swift) - Set the delegate and configure sizing using ModalSize and PresentrShadow for visual customization (
Presentr/PresentrShadow.swift)
Handle keyboard interaction in a modal
- In your presented view controller, import KeyboardTranslation utilities (
Presentr/KeyboardTranslation.swift) - Listen to UIKeyboardWillShow/UIKeyboardWillHide notifications in your view controller (
PresentrExample/PresentrExample/PopupViewController.swift) - Adjust the Presentr frame or view controller's view frame using keyboard height from the notification (
Presentr/PresentrController.swift) - Re-present the view controller with updated frame calculations after keyboard state changes (
Presentr/Presentr.swift)
🔧Why these technologies
- UIViewControllerTransitioningDelegate & UIPresentationController — iOS 8+ standard APIs for custom presentations; allows fine-grained control over modal appearance, sizing, and animations without subclassing UIViewController
- UIViewPropertyAnimator & CABasicAnimation — Modern animation framework (post-iOS 10) provides interactive, interruptible animations; CABasicAnimation used for more complex property transitions like 3D flip
- Swift Protocol-oriented design — PresentrAnimation protocol allows pluggable animator implementations; enables composition-based extension without inheritance
- CocoaPods & Carthage distribution — Makes framework easily integrable into existing projects; reduces barrier to adoption across different dependency management strategies
⚖️Trade-offs already made
-
Single presentation delegate (Presentr class) manages all configuration rather than separate builders
- Why: Simpler API surface; fewer objects to manage; faster learning curve for new developers
- Consequence: Presentr class carries multiple responsibilities (config holder + presentation orchestrator); mutations require re-creating instances for thread safety
-
Frame calculations in PresentrController rather than delegating to separate LayoutEngine
- Why: Reduces number of classes; keeps sizing logic colocated with layout application
- Consequence: PresentrController.swift is larger and mixes concerns; harder to unit test frame calculations in isolation
-
Pre-built AlertViewController with .xib instead of only providing base framework
- Why: Provides immediate value for common use case; serves as documentation of best practices
- Consequence: Framework carries UI component dependency; may feel opinionated for users wanting
🪤Traps & gotchas
Swift version constraint: Project pins .swift-version to Swift 4.2; upgrading to Swift 5+ requires explicit migration, compiler flags, and testing across multiple Xcode versions. Keyboard handling complexity: KeyboardTranslation.swift wraps UIKeyboardWillShow/Hide notifications but may not handle all edge cases on iOS 14+ (keyboard types, InputAccessoryView, Safe Area). XIB-based AlertViewController: If using AlertViewController, remember it's XIB-loaded; runtime errors if bundle resources are misconfigured. No test suite visible: No Tests/ or XCTest files in structure suggests minimal automated test coverage; manual QA required. Carthage + CocoaPods dual support: Both package managers defined but may diverge if only one is actively maintained.
🏗️Architecture
💡Concepts to learn
- UIViewControllerTransitioningDelegate — Core iOS API that Presentr wraps; understanding this protocol (animationController(forPresented:), presentationController(forPresented:)) is essential to grasping how Presentr intercepts and customizes presentations
- UIPresentationController — Manages the presentation environment (layout, dimming, gesture handling) that Presentr customizes via PresentrController; critical for understanding how modals are sized and positioned off-screen
- CABasicAnimation & UIViewPropertyAnimator — Underlying animation mechanism used in Presentr animation subclasses (e.g., CoverVerticalAnimation.swift, FlipHorizontalAnimation.swift); understanding frame-based and property-based animations is key to extending or debugging transitions
- Modal Presentation Strategy Pattern — Presentr uses strategy pattern (PresentationType enum, ModalSize enum) to decouple presentation logic from presentation style; learning this design allows safe extension of new presentation modes without modifying core coordinator
- Safe Area & Adaptive Layout — ModalCenterPosition.swift and presentation calculations must respect Safe Area (notches, Home Indicator); this is non-obvious on iPad Split View and modern iPhones, a common source of bugs in custom presentations
- Interactive Transitions & Gesture Recognizers — PresentrAnimation supports interactive transitions via UIPercentDrivenInteractiveTransition; understanding gesture-driven dismissal (pan, tap outside) is important for polishing user experience in custom modals
- XIB-based View Loading & Bundle Resources — AlertViewController.swift loads its UI from AlertViewController.xib; understanding when and how XIBs are bundled with frameworks is crucial to avoid missing resource runtime errors in framework integrations
🔗Related repos
hackiftekhar/IQKeyboardManager— Complementary library for iOS keyboard management; often paired with Presentr to handle keyboard overlapping presented view controllersairbnb/lottie-ios— Animation library for iOS; developers using Presentr for custom animations often combine it with Lottie for complex transition graphicsrealm/realm-swift— Data persistence framework; example apps and real-world Presentr-based modals often fetch/display data backed by RealmReactiveX/RxSwift— Reactive programming library for Swift; modern Presentr-based apps often use RxSwift for coordinating presentation lifecycle and dismissal eventsjvanakera/iOS-custom-controls— Historic predecessor demonstrating custom UIViewController presentation techniques; Presentr abstracts and simplifies these lower-level patterns into a usable framework
🪄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 PresentrAnimation protocol implementations
The repo has 6 animation classes (CoverFromCornerAnimation, CoverHorizontalAnimation, CoverVerticalAnimation, CoverVerticalFromTopAnimation, FlipHorizontalAnimation, CrossDissolveAnimation) but PresentrTests/PresentrTests.swift appears to have minimal coverage. These animation classes are core to the library's value proposition and need specific tests for timing, frame calculations, and state transitions.
- [ ] Expand PresentrTests/PresentrTests.swift with test cases for each animation class in Presentr/ (CoverFromCornerAnimation.swift, CoverHorizontalAnimation.swift, etc.)
- [ ] Add tests verifying animation duration, initial/final frame positions, and transform calculations
- [ ] Test edge cases like animations on different device orientations and screen sizes
- [ ] Verify PresentrAnimation protocol conformance for each implementation
Add GitHub Actions CI workflow for Swift linting and testing
The repo has a .swiftlint.yml configuration file but no automated CI enforcement. There's a .github/PULL_REQUEST_TEMPLATE.md but no corresponding GitHub Actions workflow. This allows linting violations and test failures to slip into main. A Swift-focused CI workflow would catch issues early.
- [ ] Create .github/workflows/swift-ci.yml with jobs for: SwiftLint (referencing .swiftlint.yml), Swift build, and unit tests (PresentrTests/)
- [ ] Configure the workflow to run on pull requests and pushes to main
- [ ] Add matrix testing for Swift versions specified in .swift-version
- [ ] Ensure workflow validates both Presentr.xcodeproj and PresentrExample projects
Document PresentationType and ModalSize configuration patterns with code examples
The repo has PRESENTATIONTYPE.md and DELEGATE.md documentation files, but based on the file structure, there's no dedicated documentation for ModalSize.swift and ModalCenterPosition.swift configurations. New contributors struggle to understand the relationship between PresentationType.swift, ModalSize.swift, and ModalCenterPosition.swift when customizing presentations.
- [ ] Create MODALSIZE.md documenting ModalSize.swift use cases with code examples for relative, absolute, and custom sizing
- [ ] Enhance PRESENTATIONTYPE.md to include concrete examples using ModalCenterPosition.swift (referenced in file list but not documented)
- [ ] Add a configuration guide showing how PresentationType.swift, ModalSize.swift, and PresentrController.swift work together
- [ ] Reference these docs from the main README and link from PresentrExample view controllers (FirstViewController.swift, PopupViewController.swift, etc.)
🌿Good first issues
- Add Swift 5+ compatibility: audit Presentr/PresentrController.swift and Presentr/PresentrAnimation.swift for deprecated UIViewController presentation APIs (e.g., UIModalPresentationStyle changes in iOS 13+), update .swift-version file, and add a test matrix in CI for Swift 5.0–5.x
- Document keyboard behavior: create or extend KeyboardTranslation.md explaining how KeyboardTranslation.swift handles Safe Area and notched devices; add code example in PresentrExample app showing keyboard-aware presentation
- Add unit tests for ModalSize.swift: create Tests/ModalSizeTests.swift covering all ModalSize cases (Half, ThreeQuarters, Custom, Dynamic) with assertions on calculated dimensions for various screen sizes and orientations
⭐Top contributors
Click to expand
Top contributors
- @danlozano — 80 commits
- [@Malcolm Jarvis](https://github.com/Malcolm Jarvis) — 4 commits
- [@Ahsan Iqbal](https://github.com/Ahsan Iqbal) — 2 commits
- @wacumov — 2 commits
- @fpg1503 — 2 commits
📝Recent commits
Click to expand
Recent commits
bc06d3b— Update README.md (danlozano)4e2b2fc— Merge branch 'master' of github.com:IcaliaLabs/Presentr (danlozano)d7dafef— fixed podspect swift_version (danlozano)30af89a— Update README.md (danlozano)f7d6624— podspec fix (danlozano)16f995c— updated podspec (danlozano)6742a64— conditional checking support for swift 4.0 & swift 4.2 (danlozano)fed1e32— example proj fixes (danlozano)f69d4a5— Merge pull request #158 from wacumov/master (danlozano)2b70eca— Merge pull request #159 from maqtagateway/master (danlozano)
🔒Security observations
The Presentr codebase demonstrates generally good security posture as a UI library with minimal external attack surface. No critical vulnerabilities were identified. The main concerns are: (1) insecure HTTP image reference in documentation, (2) unverified embedded font files, and (3) lack of formal security documentation. The library itself is focused on view controller presentation and does not handle sensitive data, authentication, or network operations directly, which reduces the overall risk profile. No hardcoded credentials, SQL injection risks, or infrastructure issues were detected. Dependencies management should be verified in the actual Podspec file to ensure all transitive dependencies are secure.
- Medium · Insecure Image Loading from HTTP —
README.md. The README file references an image loaded from an HTTP URL (http://danielozano.com/Presentr/Screenshots/PresentrLogo.png). HTTP connections are vulnerable to man-in-the-middle attacks and should use HTTPS instead. Fix: Update the image URL to use HTTPS protocol: https://danielozano.com/Presentr/Screenshots/PresentrLogo.png - Low · Embedded Font Files Without Verification —
Presentr/Montserrat-Regular.ttf, Presentr/SourceSansPro-Regular.ttf. The project includes embedded TTF font files (Montserrat-Regular.ttf and SourceSansPro-Regular.ttf) in the bundle. While not inherently dangerous, ensure these fonts come from trusted sources and have been verified for integrity. Fix: Verify font file integrity, document their sources, and consider using system fonts or validated third-party font sources. Implement code signing to ensure bundle integrity. - Low · Missing Security Configuration Documentation —
Repository root. The codebase lacks explicit security documentation or guidelines. There is no SECURITY.md file defining vulnerability disclosure processes or security best practices for contributors. Fix: Create a SECURITY.md file documenting vulnerability disclosure policy, supported versions, and security best practices.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.