Swiftpack.co -  LeoNatan/LNPopupUI as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
A SwiftUI-friendly API for the LNPopupController framework
.package(url: "https://github.com/LeoNatan/LNPopupUI.git", from: "1.2.14")


LNPopupUI is a SwiftUI library for presenting views as popups, much like the Apple Music and Podcasts apps.

This is a SwiftUI wrapper of my LNPopupController framework, adapted to work with SwiftUI.

GitHub release GitHub stars GitHub license PayPal Donation Button

GitHub issues GitHub contributors

See a video of the modern popup look & feel here and a video of the classic popup look & feel here.

Once a popup bar is presented with a content view, the user can swipe or tap the popup at any point to present the content view. After finishing, the user dismisses the popup by either swiping or tapping the popup close button.

The library extends SwiftUI’s View with new functionality for presenting and opening popups with content views, as well as setting information such as the popup bar’s title, image and bar button items. When a popup is presented, the popup bar automatically adapts to the view it was presented on for best appearance.

Generally, it is recommended to present the popup bar on the outermost view, such as TabView or NavigationView. So if you have a view contained in a navigation view, which is in turn contained in a tab view, it is recommended to present the popup on the tab view.

Check the demo project for a quick recreation of Apple’s music app.


  • Available for iOS 13 and above, as a SPM package for SwiftUI
  • A SwiftUI library, wrapping my LNPopupController framework; the library works internally with SwiftUI’s generated UIKit content to present the framework in a native manner

Adding to Your Project

Swift Package Manager

LNPopupUI supports SPM versions 5.1.0 (Xcode 11) and above. In Xcode, click File -> Swift Packages -> Add Package Dependency, enter https://github.com/LeoNatan/LNPopupUI. Select the version you’d like to use.

You can also manually add the package to your Package.swift file:

.package(url: "https://github.com/LeoNatan/LNPopupUI.git", from: "1.0.0")

And the dependency in your target:

.target(name: "BestExampleApp", dependencies: ["LNPopupUI"]),

Using the Library

Project Integration

Import the module in your project:

import LNPopupUI


Popup consist of a popup bar and a popup content view. Information for the popup bar, such as the title, image and bar button items, is received by using the provided modifier API.

To present the popup, call the popup(isBarPresented:isPopupOpen:content) method:

TabView {
	//Top content view
.popup(isBarPresented: $isPopupBarPresented, isPopupOpen: $isPopupOpen) {
	PlayerView(song: currentSong)

To present and dismiss the popup bar programmatically, toggle the isPopupBarPresented bound var. To open or close the popup programmatically, toggle the isPopupOpen bound var.

For more information, see the documentation in LNPopupUI.swift.

Popup Bar Content

Popup bar content is provided as modifiers of the popup content view.

VStack {
	//Popup content view
	HStack(spacing: 20) {
		Button(action: {
		}) {
			Image(systemName: "play.fill")

		Button(action: {
		}) {
			Image(systemName: "forward.fill")

Appearance and Behavior

LNPopupUI provides two distinct style of popup look and feel, one based on modern Music app look and feel, and one based on the previous, iOS 9-style look and feel. Popup bar styles are arbitrarily labeled "prominent" for modern style popup bar and "compact" for iOS 9-style. Popup interaction styles are labeled "snap" for modern style snapping popups and "drag" for iOS 9 interactive popup interaction. Popup close buttons styles are labeled "chevron" for modern style chevron close button and "round" for iOS 9-style close buttons. For each, there is a "default" style for choosing the most suitable one for the current operating system version.

The defaults are:

  • Prominent bar style
  • Snap interaction style
  • Chevron close button style
  • No progress view style

Bar Style

Customizing the popup bar style is achieved by calling the .popupBarStyle() modifier.

.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
	//Popup content view

Interaction Style

Customizing the popup interaction style is achieved by calling the .popupInteractionStyle() modifier.

.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
	//Popup content view

Progress View Style

Customizing the popup bar progress view style is achieved by calling the .popupBarProgressViewStyle() modifier.

.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
	//Popup content view

To hide the progress view, set the bar progress view style to .none.

Close Button Style

Customizing the popup close button style is achieved by calling the .popupCloseButtonStyle() modifier.

.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
	//Popup content view

To hide the popup close button, set the popupCloseButtonStyle to LNPopupCloseButtonStyleNone / .none.

Custom Popup Bar View

You can display your own view as the popup bar, instead of the system-provided ones, by using the .popupBarCustomView() modifier.

.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
	//Popup content view
.popupBarCustomView(wantsDefaultTapGesture: false, wantsDefaultPanGesture: false, wantsDefaultHighlightGesture: false) {
  //Custom popup bar view content

The wantsDefaultTapGesture, wantsDefaultPanGesture and wantsDefaultHighlightGesture arguments control whether the default system gestures of the popup bar should be enabled or disabled.

Context Menus

You can add a context menu to your popup bar by calling the .popupBarContextMenu() modifier.

.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
	//Popup content view
.popupBarContextMenu {
	Button(action: {
		print("Context Menu Item 1")
	}) {
		Text("Context Menu Item 1")
		Image(systemName: "globe")
	Button(action: {
		print("Context Menu Item 2")
	}) {
		Text("Context Menu Item 2")
		Image(systemName: "location.circle")

Lower-level Bar Customization

LNPopup exposes the .popupBarCustomizer() modifier, which allows lower-level customization through the UIKit LNPopupBar object.

.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
	//Popup content view
.popupBarCustomizer { popupBar in
	let paragraphStyle = NSMutableParagraphStyle()
	paragraphStyle.alignment = .right
	paragraphStyle.lineBreakMode = .byTruncatingTail

	popupBar.inheritsVisualStyleFromDockingView = false
	popupBar.backgroundStyle = .dark
	popupBar.titleTextAttributes = [ .paragraphStyle: paragraphStyle, .font: UIFont(name: "Chalkduster", size: 14)!, .foregroundColor: UIColor.yellow ]
	popupBar.subtitleTextAttributes = [ .paragraphStyle: paragraphStyle, .font: UIFont(name: "Chalkduster", size: 12)!, .foregroundColor: UIColor.green ]
	popupBar.tintColor = .yellow

Full Right-to-Left Support

The library has full right-to-left support.


The library uses:

Additionally, the demo project uses:

  • LoremIpsum Copyright (c) 2013-2020 Lukas Kubanek


Stars: 78
Last commit: 3 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Release Notes

3 weeks ago
  • Added popupBarInheritsAppearanceFromDockingView(_:) and popupBarBackgroundEffect(_:) modifiers
  • Deprecated popupBarBackgroundStyle(_:)
  • Internal changes to use the modern appearance API of LNPopupController

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API