Library / SDK
LeoNatan/LNPopupController avatar
LeoNatan/LNPopupController

LNPopupController: UIKit popup bars for mini-players and docked view controllers

A framework for presenting view controllers as popups of other view controllers, much like the Apple Music and Podcasts apps.

3,143 stars351 forksObjective-C++MIT

At a glance

What is it?
LNPopupController is an MIT-licensed Objective-C and Swift framework that docks a popup bar and a presentable content view controller to a container controller, the way the Apple Music and Podcasts mini-players work. It is a UIKit category, not a SwiftUI view, and the README points SwiftUI users at a separate library.
Who is it for?
Adopt LNPopupController when your app is UIKit-first and you want the mini-player pattern without writing your own docked bar, safe-area bookkeeping and gesture handling. Skip it if your interface is SwiftUI-first, since the README directs that case to the separate LNPopupUI library, and skip it if you need a popup system that is not tied to UIViewController containment.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 12 days ago.
What is it written in?
Mainly Objective-C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem LNPopupController solves for UIKit apps

Apple Music and Podcasts both show a small bar at the bottom of the screen while something is playing. Tapping or swiping it expands a full content view controller over the current screen, and swiping down or tapping a close button collapses it again. Reproducing that by hand means managing a container view, a bar view, presentation and dismissal animations, gesture recognizers, and the safe area insets of every child controller while the bar is visible. LNPopupController packages that pattern. The README describes it as a framework for presenting view controllers as popups of other view controllers, similar to those two Apple apps, and says it is implemented as a category over UIViewController so that each view controller can present a popup bar docked to a bottom view. It is aimed at UIKit developers on iOS, iPadOS and Mac Catalyst who want the mini-player interaction without building the plumbing. The README states availability for iOS 13 and later as an SPM package for Swift and Objective C, and notes support for iOS 27 and iOS 26 glass design while keeping an appropriate look on earlier versions.

How the popup bar, popup item and container controller fit together

The architecture is built on three roles. A popup container controller is the UIViewController that hosts the presentation. A content view controller is what appears inside the popup. A popup item, an instance of LNPopupItem, carries the information the bar displays, and the README says the bar's information is provided dynamically through popup items associated with the popup content view controllers, so changing what the bar shows means updating that view controller's popup item. Docking is decided by container type: for UITabBarController and its subclasses the default docking view is the tab bar, for UINavigationController and its subclasses it is the toolbar, and for other view controllers the bar is presented at the bottom of the screen. Subclasses can supply their own docking views. The README recommends presenting the bar on the outermost container controller, so a view controller inside a navigation controller inside a tab bar controller should present on the tab bar controller. The framework also maintains the safe area insets of the container and its children as the bar appears and disappears, which is the part most hand-rolled implementations get wrong. Beyond the default item source, the README documents a popup item data source for advanced setups and popup item paging.

Installing LNPopupController with Swift Package Manager

The README gives two installation routes: the Xcode UI, through File then Add Package Dependencies, entering the repository URL, and manual editing of Package.swift. The README states that SPM versions 6.0 (Xcode 16) and later are supported. The manual form adds the package with a version range starting at 4.0.0:

swift
.package(url: "https://github.com/LeoNatan/LNPopupController.git", from: "4.0.0")

The dependency then goes into your target:

swift
.target(name: "MyExampleApp", dependencies: ["LNPopupController"]),

Source files import the module:

swift
import LNPopupController

After importing, the first real step is to present a popup bar on a container controller and give the content controller a popup item, following the README's recommendation to present on the outermost container. If you want to see working configurations before writing your own, the README points at the demo project and notes it contains examples in Swift and Objective C. It also warns that running the example project requires updating submodules first:

bash
git submodule update --init --recursive

What you should see after that command is the submodule contents populated so the example project can build; without it, the README implies the example will not run correctly.

Where LNPopupController is the wrong choice

The clearest boundary is SwiftUI. The README does not present this framework as a SwiftUI solution; it explicitly directs SwiftUI users to a separate LNPopupUI library. If your screens are SwiftUI views, adopting this framework means bridging into UIKit containment, and the README offers no SwiftUI integration path here. A second boundary is the containment model itself. The framework is a category over UIViewController, and its docking defaults are derived from the container's class: tab bar controllers dock to the tab bar, navigation controllers to the toolbar, everything else to the bottom of the screen. If your layout does not map onto that containment hierarchy, you are in the territory of custom popup container view controllers and custom popup bars, which the README lists as advanced topics with an example implementation. Third, the README does not document rollback, version pinning policy or a migration guide for breaking changes, so a team that needs a documented upgrade path has to read the release history instead. Finally, the README's own framing is that the framework is intended to be very generic; if you want a popup that is deliberately non-generic, tightly coupled to one screen, this is more machinery than the job needs.

Alternatives and how their approach differs

The alternative the README itself names is LNPopupUI, by the same author, for SwiftUI. The difference is not cosmetic: LNPopupController is a UIViewController category that relies on UIKit containment and docking views, while a SwiftUI library has to express the same mini-player behaviour through SwiftUI's own view and state model. Choosing between them follows from which UI framework your app is built on, not from a feature comparison. Outside that pair, the honest alternative is building the bar yourself: a child view controller or a plain view pinned above the safe area, with your own gesture recognizers and presentation animation. That gives you complete control over the transition and the bar's contents, and it avoids a dependency, but you take on the safe-area inset maintenance that the README calls out as something the framework handles for the container and its children, plus the platform-specific behaviour the README lists, such as window resize on iPadOS and Mac Catalyst, split view controllers, tab bar sidebar, pointer interactions and right-to-left layout. Whether that list matters to you is the real decision point.

Maintenance, licence and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-19, the same day as the 4.5.12 release. Releases 4.5.11 and 4.5.10 landed on 2026-09-18, so the project has seen three releases in two days, which is a burst rather than a cadence you can plan around; the README does not publish a release schedule or a support window, so upgrade cost has to be judged from the release notes of each version. The licence is MIT, which permits use in closed-source applications and requires preserving the copyright notice and licence text; that is a summary of the licence identifier, not legal advice, and your own counsel should confirm obligations. The practical upgrade cost is tied to platform support: the README states iOS 13 and later and SPM 6.0 (Xcode 16) and later, and it advertises support for iOS 27 and iOS 26 glass design while maintaining an appropriate look on previous versions. That means visual behaviour can change with an OS release even when your dependency version does not. The README does not document a deprecation policy for the legacy bar styles it mentions, so if you depend on those, treat each release as something to check rather than assume.

Editorial conclusion

Adopt LNPopupController when your app is UIKit-first and you want the mini-player pattern without writing your own docked bar, safe-area bookkeeping and gesture handling. Skip it if your interface is SwiftUI-first, since the README directs that case to the separate LNPopupUI library, and skip it if you need a popup system that is not tied to UIViewController containment. Before committing, verify the Package.swift dependency resolves against your Xcode version, confirm the demo project builds after running git submodule update --init --recursive, and check that the docking behaviour you want is listed for your container type in the README's docking rules rather than assuming it.

Frequently asked questions

Does LNPopupController work with SwiftUI?

The README treats SwiftUI as a separate case and points readers to the LNPopupUI library instead. LNPopupController itself is described as a category over UIViewController, so its model is UIKit containment.

Which iOS versions does LNPopupController support?

The README states it is available for iOS 13 and later as an SPM package for Swift and Objective C, and that it supports iOS 27 and iOS 26 glass design while keeping an appropriate look on previous iOS versions.

How do I install LNPopupController with Swift Package Manager?

In Xcode, use File then Add Package Dependencies and enter the repository URL, or add .package(url: "https://github.com/LeoNatan/LNPopupController.git", from: "4.0.0") to Package.swift and list LNPopupController as a target dependency. The README states SPM versions 6.0 (Xcode 16) and later are supported.

Why does the LNPopupController example project not run?

The README notes that to run the example project you need to update submodules first with git submodule update --init --recursive. Without that step the example project is not in a runnable state.

Official sources

  1. Issues
  2. LeoNatan/LNPopupController on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/leonatan-lnpopupcontroller.svg)](https://hysenlabs.com/projects/leonatan-lnpopupcontroller)