Daltron/NotificationBanner
The easiest way to display highly customizable in app notification banners in iOS
Stale — last commit 2y ago
worst of 4 axeslast commit was 2y ago; no tests detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓36+ active contributors
- ✓MIT licensed
- ✓CI configured
Show 3 more →Show less
- ⚠Stale — last commit 2y ago
- ⚠Concentrated ownership — top contributor handles 53% of recent commits
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy 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.
[](https://repopilot.app/r/daltron/notificationbanner)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/daltron/notificationbanner on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: Daltron/NotificationBanner
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/Daltron/NotificationBanner 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 2y ago
- 36+ active contributors
- MIT licensed
- CI configured
- ⚠ Stale — last commit 2y ago
- ⚠ Concentrated ownership — top contributor handles 53% of recent commits
- ⚠ 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 Daltron/NotificationBanner
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/Daltron/NotificationBanner.
What it runs against: a local clone of Daltron/NotificationBanner — 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 Daltron/NotificationBanner | 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 ≤ 680 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Daltron/NotificationBanner. If you don't
# have one yet, run these first:
#
# git clone https://github.com/Daltron/NotificationBanner.git
# cd NotificationBanner
#
# 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 Daltron/NotificationBanner and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Daltron/NotificationBanner(\\.git)?\\b" \\
&& ok "origin remote is Daltron/NotificationBanner" \\
|| miss "origin remote is not Daltron/NotificationBanner (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 "NotificationBanner/Classes/BaseNotificationBanner.swift" \\
&& ok "NotificationBanner/Classes/BaseNotificationBanner.swift" \\
|| miss "missing critical file: NotificationBanner/Classes/BaseNotificationBanner.swift"
test -f "NotificationBanner/Classes/NotificationBanner.swift" \\
&& ok "NotificationBanner/Classes/NotificationBanner.swift" \\
|| miss "missing critical file: NotificationBanner/Classes/NotificationBanner.swift"
test -f "NotificationBanner/Classes/NotificationBannerQueue.swift" \\
&& ok "NotificationBanner/Classes/NotificationBannerQueue.swift" \\
|| miss "missing critical file: NotificationBanner/Classes/NotificationBannerQueue.swift"
test -f "NotificationBanner/Classes/BannerStyle.swift" \\
&& ok "NotificationBanner/Classes/BannerStyle.swift" \\
|| miss "missing critical file: NotificationBanner/Classes/BannerStyle.swift"
test -f "NotificationBanner/Classes/FloatingNotificationBanner.swift" \\
&& ok "NotificationBanner/Classes/FloatingNotificationBanner.swift" \\
|| miss "missing critical file: NotificationBanner/Classes/FloatingNotificationBanner.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 680 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~650d)"
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/Daltron/NotificationBanner"
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
NotificationBanner is a lightweight Swift library that displays highly customizable in-app notification banners and dropdown alerts for iOS apps. It handles multiple banner styles (basic, growing, floating, stacked, status bar) with support for custom views, colors, NSAttributedString content, and haptic feedback—eliminating boilerplate code for notification UI. Simple, single-purpose library structure: Swift framework code resides in the main NotificationBanner directory (inferred from 119KB Swift code), Example/ contains a full demo app with ExampleViewController.swift and ExampleView.swift showing all banner types, and AppIcons/ documents real production apps using the library.
👥Who it's for
iOS developers building Swift apps (iOS 12.0+) who need to show user-facing alerts and notifications without writing custom banner UI code. Developers in the Examples folder (AppIcons list includes apps like Envision, Happy Scale, Lukapizza) depend on this for consistent notification presentation.
🌱Maturity & risk
Production-ready. Written in Swift 5, supports iOS 12.0+, has a robust example app (Example/NotificationBanner.xcodeproj), CI via .travis.yml, and appears actively maintained with Dynamic Island support added. No visible test suite in file listing is a minor concern, but the library is used by 11 shipping apps (per AppIcons/).
Single-maintainer risk (Daltron owns the repo). Installation docs mention deprecation of CocoaPods/Carthage in favor of Swift Package Manager, which is a migration overhead. No visible issue backlog or recent commit dates in provided data. Lack of automated tests (.xctest files absent) limits regression detection for new iOS versions.
Active areas of work
Repo appears stable; recent additions include Dynamic Island Support (mentioned in features) and Swift Package Manager as the primary distribution method (FUNDING.yml and Package.resolved indicate SPM adoption). .travis.yml and .stale.yml suggest ongoing CI and issue triage automation.
🚀Get running
git clone https://github.com/Daltron/NotificationBanner.git && cd NotificationBanner && open Example/NotificationBanner.xcodeproj && xcodebuild -scheme NotificationBanner-Example -destination 'generic/platform=iOS Simulator'
Daily commands: Open Example/NotificationBanner.xcodeproj in Xcode 10.0+, select NotificationBanner-Example scheme, and run on iOS 12.0+ simulator or device. The Example app (ExampleViewController.swift) showcases all banner styles interactively.
🗺️Map of the codebase
NotificationBanner/Classes/BaseNotificationBanner.swift— Core abstract banner class that all notification types inherit from; defines the primary lifecycle, customization API, and queue management logic.NotificationBanner/Classes/NotificationBanner.swift— Main banner implementation with title/subtitle rendering; most common entry point for developers using the library.NotificationBanner/Classes/NotificationBannerQueue.swift— Manages sequential display of multiple banners; critical for handling concurrent show requests and animation timing.NotificationBanner/Classes/BannerStyle.swift— Enum defining all supported banner styles (top, bottom, floating, status bar); used everywhere to determine layout and animation behavior.NotificationBanner/Classes/FloatingNotificationBanner.swift— Specialized floating banner subclass; demonstrates how to extend BaseNotificationBanner for custom presentation modes.NotificationBanner/Classes/StatusBarNotificationBanner.swift— Specialized status bar banner subclass; shows system-level integration patterns used by the library.NotificationBanner/Classes/BannerColors.swift— Centralized theme/color configuration; defines default color schemes and customization patterns.
🧩Components & responsibilities
- BaseNotificationBanner (UIView, Auto Layout, UIGestureRecognizer, NotificationBannerQueue) — Manages banner lifecycle (initialization, frame calculation, animation, dismissal), layout via auto layout constraints, gesture recognizer setup, and queue coordination
- Failure mode: If layout constraints fail, banner may misposition or cause layout errors; if queue coordination breaks, multiple banners display simultaneously
- NotificationBannerQueue —
🛠️How to make changes
Add a New Banner Style Variant
- Create a new style case in the BannerStyle enum to define positioning and animation direction (
NotificationBanner/Classes/BannerStyle.swift) - Subclass BaseNotificationBanner to customize frame calculation and animation behavior for the new style (
NotificationBanner/Classes/FloatingNotificationBanner.swift) - Update BannerPositionFrame to calculate screen coordinates for the new style variant (
NotificationBanner/Classes/BannerPositionFrame.swift) - Add demo cell in the example app table view showing how to instantiate the new banner variant (
Example/NotificationBanner/ExampleViewController.swift)
Add Custom Colors/Theme
- Define new color constants in BannerColors as static properties or create a new color scheme struct (
NotificationBanner/Classes/BannerColors.swift) - Initialize banner with custom backgroundColor, textColor, and shadowColor properties (
NotificationBanner/Classes/NotificationBanner.swift) - Reference the custom colors when instantiating banners in your view controller (
Example/NotificationBanner/CustomBannerColors.swift)
Add Custom Banner Content View
- Create a custom UIView subclass with your desired layout and content (
Example/NotificationBanner/NorthCarolinaBannerView.swift) - Initialize BaseNotificationBanner with the customView parameter instead of title/subtitle (
NotificationBanner/Classes/BaseNotificationBanner.swift) - Set banner properties like duration, dismissOnTap, and queue behavior before calling show() (
Example/NotificationBanner/ExampleViewController.swift)
Configure Queue Behavior for Multiple Banners
- Access NotificationBannerQueue.default to get the singleton queue instance (
NotificationBanner/Classes/NotificationBannerQueue.swift) - Call banner.show() which automatically enqueues the banner for sequential display (
NotificationBanner/Classes/BaseNotificationBanner.swift) - Optionally configure duration, dismissal callback, and haptic feedback via banner initializer properties (
NotificationBanner/Classes/NotificationBanner.swift)
🔧Why these technologies
- Swift 5 + UIKit — Native iOS framework for maximum performance, tight system integration, and direct access to view animations and haptic feedback APIs
- Auto Layout with UIView.animate() — Simplifies responsive positioning across different device sizes and orientations; UIView.animate provides smooth, performant property-based animations
- Singleton Queue Pattern (NotificationBannerQueue) — Ensures only one banner displays at a time, preventing overlapping animations and providing predictable sequential behavior across the entire app
- Subclassing (FloatingNotificationBanner, StatusBarNotificationBanner) — Allows behavioral variation while reusing core lifecycle and queue management; cleaner than conditionals for different presentation modes
⚖️Trade-offs already made
-
Global singleton queue vs. per-window queue
- Why: Simpler API and predictable single-banner-at-a-time behavior desired by most apps
- Consequence: Cannot display banners in different windows simultaneously; all banners serialize through one queue
-
Subclassing BaseNotificationBanner vs. composition/protocols
- Why: OOP approach is familiar to UIKit developers and allows straightforward lifecycle override
- Consequence: More rigid than protocol-based design; harder to mix behaviors from multiple banner types
-
Fixed duration + manual dismiss vs. gesture-driven interaction
- Why: Simplest implementation and meets 80% of use cases; automatic dismissal after timeout reduces developer burden
- Consequence: Apps with complex interaction requirements must subclass and override dismiss logic
🚫Non-goals (don't propose these)
- Real-time notification delivery (does not handle push notification registration or APNs integration)
- Persistent notification history or logging (banners are ephemeral UI elements only)
- Animation customization beyond preset styles (no keyframe or CoreAnimation timeline control exposed)
- SwiftUI support (UIKit-only library; does not provide SwiftUI wrappers or native SwiftUI banners)
- Notification permissions or user consent management (does not interact with notification settings)
🪤Traps & gotchas
Swift Package Manager (SPM) is now the only recommended installation method; CocoaPods/Carthage support is deprecated and docs warn against using them. The Example app requires iOS 12.0+ and Xcode 10.0+ minimum versions—older toolchains will fail. Dynamic Island support requires runtime detection code (not visible in file list but mentioned in features), so custom views on older iOS may need conditional logic. No visible unit test suite means local changes require manual testing via the Example app.
🏗️Architecture
💡Concepts to learn
- CABasicAnimation (Core Animation) — NotificationBanner uses Core Animation for smooth banner entrance/exit animations (top-to-bottom slide, fade); understanding CABasicAnimation is essential for modifying timing or adding custom animation types
- UIView.animate() & CATransaction — Banner presentation and dismissal rely on implicit CATransaction batching; knowledge of transaction timing is needed to synchronize banner queue display
- Safe Area Layout & notch/Dynamic Island avoidance — Banners must respect safe area insets for iPhoneX/14 Pro models and avoid the Dynamic Island; understanding layoutMargins and safeAreaInsets is critical for proper positioning
- UIViewPropertyAnimator & gesture recognition — Banners support swipe-to-dismiss and long-press interactions; UIViewPropertyAnimator enables interruptible dismissal animations
- NSAttributedString styling — Library explicitly supports NSAttributedString for rich text (colors, fonts, styles in title/subtitle); critical for apps needing formatted notification text
- Queue data structure & thread-safe access — Built-in banner queue manages simultaneous vs. sequential display; understanding FIFO queue semantics and DispatchQueue (for thread safety) is needed to extend banner ordering logic
- Haptic feedback (UIImpactFeedbackGenerator) — Library triggers haptic feedback on banner display; UIImpactFeedbackGenerator requires iOS 13+ conditional compilation and understanding of haptic styles (light, medium, heavy)
🔗Related repos
brynbellomy/Notchy— Similar in-app notification UI library for iOS, provides alternative banner styles and queue managementjonkykong/SideMenu— Complementary iOS UI library for dropdown/slide-out alerts; often used alongside notification banners in the same appCombineCommunity/CombineExt— Ecosystem companion if NotificationBanner adopts Combine for reactive banner state management in future versionsvapor/vapor— Not directly related but Daltron may maintain server-side notification logic; listed here as maintainer's other work context
🪄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 iOS 14+ Safe Area and Dynamic Island support for Status Bar Banners
The repo shows StatusBar banner examples in the README but the codebase likely lacks proper handling for Dynamic Island (iPhone 14+) and Safe Area edge cases. This is a concrete feature gap that affects modern iOS devices. New contributors can enhance the banner positioning logic to detect and accommodate Dynamic Island cutouts and notches.
- [ ] Review the NotificationBanner/Sources files to identify StatusBar banner positioning logic
- [ ] Add device detection for Dynamic Island (checking for notch/island presence)
- [ ] Implement Safe Area layout guide integration for proper banner positioning on iPhone 14+
- [ ] Add example in Example/NotificationBanner/ExampleViewController.swift demonstrating Dynamic Island compatibility
- [ ] Test across multiple device simulators (iPhone 13, 14, 14 Pro)
Create comprehensive unit tests for NotificationBanner core functionality
The file structure shows Example/ and AppIcons/ folders but notably lacks a Tests/ directory. Given this is a UI library with multiple banner types (Basic, Side Views, Status Bar, Growing), there should be unit tests for banner lifecycle, customization options, and edge cases. This is critical for maintainability.
- [ ] Create Tests/ folder structure mirroring NotificationBanner/Sources
- [ ] Add unit tests for NotificationBanner initialization with various configuration options
- [ ] Add tests for banner show/dismiss lifecycle and timing behavior
- [ ] Add tests for CustomBannerColors customization logic (colors, fonts, backgrounds)
- [ ] Add tests for side view rendering and layout constraints
- [ ] Configure test target in Example/NotificationBanner.xcodeproj/project.pbxproj
Add GitHub Actions CI workflow for Swift package validation and Example app builds
The repo has .travis.yml (legacy Travis CI) but needs a modern GitHub Actions workflow. The file structure shows an Xcode project at Example/NotificationBanner.xcodeproj that should be built and tested on each PR. This ensures contributions don't break compilation across iOS versions.
- [ ] Create .github/workflows/swift-build.yml with jobs for Swift Package validation
- [ ] Add matrix strategy to test against multiple Swift versions (5.5+) and iOS deployment targets
- [ ] Configure job to build Example/NotificationBanner.xcodeproj using xcodebuild
- [ ] Add job to run unit tests (created from PR #2) on each commit
- [ ] Add status badge to README.md linking to GitHub Actions
- [ ] Remove or deprecate .travis.yml with a note about migration
🌿Good first issues
- Add unit tests for NotificationBanner core classes. The .xctest files are absent from the file listing; create a test target in the Xcode project with tests for banner presentation, queue management, and dismissal logic.: Improves reliability for future iOS versions and reduces single-maintainer bottleneck for PR reviews
- Add Documentation.docc/ structure with API documentation for the main NotificationBanner, GrowingNotificationBanner, and banner queue classes. Use Xcode's DocC format to auto-generate per-method docs.: Reduces onboarding friction and enables in-IDE documentation lookups for users
- Create a SwiftUI wrapper view (e.g., NotificationBannerContainer.swift) that bridges the UIKit-based library for SwiftUI projects and add an example to ExampleViewController.swift.: Modernizes the library for SwiftUI-first apps and opens a new user segment
⭐Top contributors
Click to expand
Top contributors
- @Daltron — 53 commits
- [@Menno Lovink](https://github.com/Menno Lovink) — 5 commits
- [@Michael Steudter](https://github.com/Michael Steudter) — 3 commits
- @chickdan — 2 commits
- @martinmaly21 — 2 commits
📝Recent commits
Click to expand
Recent commits
9550d28— Add PrivacyInfo file (#430) (chickdan)896d5fa— Update README.md (Daltron)be52806— Update Dependencies for Privacy Manifest (#426) (chickdan)1406ac6— Updated license file (Daltron)9d5af4e— Updated launch screen (Daltron)87690cb— Removed CocoaPods from example project (Daltron)7eab3ee— Fix rightView layout (#412) (truongtho1603)eaa40b9— Fixed bug where banner would have an incorrect height for iPhones with dynamic island (#405) (martinmaly21)6d85d0d— Default bannerPosition to .top (#409) (martinmaly21)9b97372— Update README.md (Daltron)
🔒Security observations
The NotificationBanner iOS library demonstrates generally good security practices for a Swift UI framework. No critical vulnerabilities were identified in the file structure. The codebase lacks apparent hardcoded credentials, SQL injection vectors, or XSS risks typical of web applications. Primary concerns are related to dependency management practices and the absence of explicit security documentation. The library's focus on UI notifications minimizes attack surface. Recommendations include implementing automated dependency scanning, establishing a security policy, and ensuring proper handling of security reports through responsible disclosure channels.
- Low · Missing Package.resolved Lock File Analysis —
Example/NotificationBanner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved, NotificationBanner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved. The repository contains Swift Package Manager resolved files (Package.resolved) which should be reviewed for known vulnerabilities in dependencies. The specific versions and vulnerability status cannot be determined from the file structure alone. Fix: Review Package.resolved files for outdated dependencies usingswift package updateand check each dependency against known vulnerability databases (CVE, GitHub Security Advisories). Implement automated dependency scanning in CI/CD pipeline. - Low · No Apparent Security Policy —
.github/. While .github configuration files are present, there is no evidence of a SECURITY.md file or security policy for reporting vulnerabilities responsibly. Fix: Create a SECURITY.md file in the root directory or .github/ folder with clear instructions for responsible vulnerability disclosure and security contact information. - Low · Potential Stale Repository Check —
.github/stale.yml. The presence of .github/stale.yml suggests the repository may use automated stale issue/PR closing, which could mask security-related reports if not properly triaged. Fix: Review the stale.yml configuration to ensure security-related issues and pull requests are not automatically closed. Consider exempting security-labeled issues from auto-closing.
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.