mshibanami/popopover
Popopover is a lightweight SwiftUI wrapper for displaying native popover UIs.
Demo
iPhone:
https://github.com/user-attachments/assets/c411a082-2535-48bc-8f65-02e42ffddeb8
Mac:
https://github.com/user-attachments/assets/7ab55bb6-a48c-4a49-8be4-3d1a3c090287
Why not the built-in `popover()`?
SwiftUI’s official popover()) method has limitations, and Popopover was created to address them:
- More flexibility: Popopover offers more options for customizing the appearance and behavior of the popover, such as preventing users from closing it by tapping outside, or creating a detachable popover (on Mac).
- No UI changes: On iOS, the
popover()method may add extra padding around the content, which is not always desirable (learn more). Our goal is to make a pure wrapper for the native popover, so it doesn’t add any padding like that. - Older OS support: If you want to display a popover UI on any device (iPhone or iPad) using
popover(), you need to specifypresentationCompactAdaptation(.popover)) to force it. However, that modifier is only available on iOS 16.4+ and macOS 13.3+. Popopover supports iOS 13+ and macOS 10.15+, allowing you to display popovers even on older OS versions.
Additionally, Popopover offers the following advantages:
- Complete implementation: While creating a simple SwiftUI wrapper around the native popover is easy, there are still potential issues such as missing animations or incorrect view sizing. Popopover is designed for developers who want a reliable, fully implemented wrapper.
popover()-compatible API: Popopover is designed with an API that closely mirrorspopover(), making it easy to integrate or migrate existing code with minimal changes. Just add "po" prefix topopover()to switch to Popopover!
Getting Started
To use Popopover, simply add the Popopover package to your Swift project. You can do this by adding the following line to your Package.swift file:
.package(url: "https://github.com/mshibanami/Popopover.git", from: "1.0.0")To show a popover using Popopover, you can use the popopover() method on any SwiftUI view. Here's an example:
import SwiftUI
import Popopover
struct ContentView: View {
@State private var isPopoverPresented = false
var body: some View {
Button("Show Popover") {
isPopoverPresented = true
}
.popopover(isPresented: $isPopoverPresented, arrowEdge: .bottom) {
Text("Hello, Popopover!")
.padding()
}
}
}You can find a example Xcode project in Examples.
API
The popopover(...) method has a similar API to the SwiftUI's built-in popover() method.
Parameters
| Name | Description | | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | isPresented | The same as popover's isPresented parameter. | | attachmentAnchor | The same as popover's attachmentAnchor parameter. | | arrowEdge | The same as popover's arrowEdge parameter. | | behavior | The appearance and disappearance behavior of a popover.<br><ul><li><code>.transient</code> (default) dismisses the popover when the user clicks outside of it.</li><li><code>.applicationDefined</code> requires explicit dismissal by the app.</li><li><code>.semitransient</code> (macOS only) is similar to <code>.transient</code>, but allows interaction with elements in other windows or other apps.</li></ul> | | isDetachable | (macOS only) A Boolean value that indicates whether the popover can be detached from its source view and become a separate window. | | content | The same as popover's content parameter. |
License
MIT
Apps that use this package
Package Metadata
Repository: mshibanami/popopover
Default branch: main
README: README.md