Home

Awesome

<a href="https://exyte.com/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/exyte/media/master/common/header-dark.png"><img src="https://raw.githubusercontent.com/exyte/media/master/common/header-light.png"></picture></a>

<a href="https://exyte.com/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/exyte/media/master/common/our-site-dark.png" width="80" height="16"><img src="https://raw.githubusercontent.com/exyte/media/master/common/our-site-light.png" width="80" height="16"></picture></a>     <a href="https://twitter.com/exyteHQ"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/exyte/media/master/common/twitter-dark.png" width="74" height="16"><img src="https://raw.githubusercontent.com/exyte/media/master/common/twitter-light.png" width="74" height="16"> </picture></a> <a href="https://exyte.com/contacts"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/exyte/media/master/common/get-in-touch-dark.png" width="128" height="24" align="right"><img src="https://raw.githubusercontent.com/exyte/media/master/common/get-in-touch-light.png" width="128" height="24" align="right"></picture></a>

<table> <thead> <tr> <th>Floaters</th> <th>Toasts</th> <th>Popups</th> <th>Sheets</th> </tr> </thead> <tbody> <tr> <td> <img src="https://raw.githubusercontent.com/exyte/media/master/PopupView/1.gif" /> </td> <td> <img src="https://raw.githubusercontent.com/exyte/media/master/PopupView/2.gif" /> </td> <td> <img src="https://raw.githubusercontent.com/exyte/media/master/PopupView/3.gif" /> </td> <td> <img src="https://raw.githubusercontent.com/exyte/media/master/PopupView/4.gif" /> </td> </tr> </tbody> </table> <p><h1 align="left">Popup View</h1></p> <p><h4>Toasts, alerts and popups library written with SwiftUI</h4></p>

<a href="https://exyte.com/blog/swiftui-tutorial-popupview-library">Read Article »</a>

SPM Compatible Cocoapods Compatible Carthage Compatible License: MIT

What's new in version 3

Update to version 3

To include new .zoom type, AppearFrom enum cases were renamed. Instead of:

.popup(isPresented: $floats.showingTopFirst) {
    FloatTopFirst()
} customize: {
    $0
        .type(.floater())
        .appearFrom(.top) // <-- here
}

use:

.popup(isPresented: $floats.showingTopFirst) {
    FloatTopFirst()
} customize: {
    $0
        .type(.floater())
        .appearFrom(.topSlide) // <-- here
}

Update to version 2

Instead of:

.popup(isPresented: $floats.showingTopFirst, type: .floater(), position: .top, animation: .spring(), closeOnTapOutside: true, backgroundColor: .black.opacity(0.5)) {
    FloatTopFirst()
}

use:

.popup(isPresented: $floats.showingTopFirst) {
    FloatTopFirst()
} customize: {
    $0
        .type(.floater())
        .position(.top)
        .animation(.spring())
        .closeOnTapOutside(true)
        .backgroundColor(.black.opacity(0.5))
}

Using this API you can pass parameters in any order you like.

Show over navbar

To display your popup over all other views including navbars please use:

.popup(isPresented: $floats.showingTopFirst) {
    FloatTopFirst()
} customize: {
    $0.isOpaque(true)
}

This will also mean that you won't be able to tap "through" the popup's background on any of the controls "behind it" (that's because this method actually uses transparent fullscreenSheet, which won't pass the touches to underlying view). Opaque popup uses screen size to calculate its position.

Unfortunately, if opaque is false (to allow "through-touches" if you need them), popup - even if forced to be fullscreen, will be displayed under the navbar (if you know how to pass over this restriction, please do let me know in the comments). Please keep in mind that in this case the popup calculates its position using the frame of the view you attach it to, to avoid being under the navbar. So you'll likely want to attach it to the root view of your app.

Usage

  1. Add a bool to control popup presentation state
  2. Add .popup modifier to your view.
import PopupView

struct ContentView: View {

    @State var showingPopup = false

    var body: some View {
        YourView()
            .popup(isPresented: $showingPopup) {
                Text("The popup")
                    .frame(width: 200, height: 60)
                    .background(Color(red: 0.85, green: 0.8, blue: 0.95))
                    .cornerRadius(30.0)
            } customize: {
                $0.autohideIn(2)
            }
    }
}

Required parameters

isPresented - binding to determine if the popup should be seen on screen or hidden
view - view you want to display on your popup

or

item - binding to item: if item's value is nil - popup is hidden, if non-nil - displayed. Be careful - library makes a copy of your item during dismiss animation!!
view - view you want to display on your popup

Available customizations - optional parameters

use customize closure in popup modifier:

type:

floater parameters:

scroll parameters:
headerView - a view on top which won't be a part of the scroll (if you need one)

position - topLeading, top, topTrailing, leading, center, trailing, bottomLeading, bottom, bottomTrailing appearFrom - topSlide, bottomSlide, leftSlide, rightSlide, centerScale: determines the direction of appearing animation. If left empty it copies position parameter: so appears from .top edge, if position is set to .top disappearTo - same as appearFrom, but for disappearing animation. If left empty it copies appearFrom. animation - custom animation for popup sliding onto screen
autohideIn - time after which popup should disappear
dragToDismiss - true by default: enable/disable drag to dismiss (upwards for .top popup types, downwards for .bottom and default type)
closeOnTap - true by default: enable/disable closing on tap on popup
closeOnTapOutside - false by default: enable/disable closing on tap on outside of popup
backgroundColor - Color.clear by default: change background color of outside area
backgroundView - custom background builder for outside area (if this one is set backgroundColor is ignored)
isOpaque - false by default: if true taps do not pass through popup's background and the popup is displayed on top of navbar. For more see section "Show over navbar"
useKeyboardSafeArea - false by default: if true popup goes up for keyboardHeight when keyboard is displayed dismissCallback - custom callback to call once the popup is dismissed

Draggable card - sheet

To implement a sheet (like in 4th gif) enable dragToDismiss on bottom toast (see example project for implementation of the card itself)

.popup(isPresented: $show) {
    // your content 
} customize: {
    $0
        .type (.toast)
        .position(.bottom)
        .dragToDismiss(true)
}

Examples

To try PopupView examples:

Installation

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/exyte/PopupView.git")
]

CocoaPods

To install PopupView, simply add the following line to your Podfile:

pod 'ExytePopupView'

Carthage

To integrate PopupView into your Xcode project using Carthage, specify it in your Cartfile

github "Exyte/PopupView"

Requirements

Our other open source SwiftUI libraries

Grid - The most powerful Grid container
ScalingHeaderScrollView - A scroll view with a sticky header which shrinks as you scroll
AnimatedTabBar - A tabbar with a number of preset animations
MediaPicker - Customizable media picker
Chat - Chat UI framework with fully customizable message cells, input view, and a built-in media picker
OpenAI Wrapper lib for OpenAI REST API
AnimatedGradient - Animated linear gradient
ConcentricOnboarding - Animated onboarding flow
FloatingButton - Floating button menu
ActivityIndicatorView - A number of animated loading indicators
ProgressIndicatorView - A number of animated progress indicators
FlagAndCountryCode - Phone codes and flags for every country
SVGView - SVG parser
LiquidSwipe - Liquid navigation animation