Contents

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 specify presentationCompactAdaptation(.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 mirrors popover(), making it easy to integrate or migrate existing code with minimal changes. Just add "po" prefix to popover() 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