Skip to content

exyte/AnchoredPopup

Repository files navigation

     

Anchored Popup

Anchored Popup grows "out" of a trigger view, anchoring to a UnitPoint of the trigger, written with SwiftUI

SPM Compatible License: MIT

Usage

Minimal example

import AnchoredPopup

Circle()
    .useAsPopupAnchor(id: "main_menu") {
         MainMenuView()
    }

Customized example:

.useAsPopupAnchor(id: "main_menu") {
    MainMenuView()
} customize: {
    $0.position(.anchorRelative(.bottomLeading))
        .background(.none)
        .isBackgroundPassthrough(true)
        .closeOnTap(false)
}

Required parameters - useAsPopupAnchor

  • id - A unique String to store everything related to this animation, you can use it to manually launch animations using this func AnchoredPopup.launchAnchoredAnimation
  • contentBuilder - popup body builder

Optional parameters

  • position - a UnitPoint to align with UnitPoint-th part of anchor view. Could be an anchorRelative or screenRelative 'UnitPoint'
  • animation - appear/disappear animation
  • closeOnTap - enable/disable closing on tap on popup
  • closeOnTapOutside - enable/disable closing on tap on popup's background
  • isBackgroundPassthrough - enable/disable taps passing through the popup's background
  • background - Available options are:
    • .none
    • .color(Color)
    • .blur(radius: CGFloat) - blurred fullscreen overlay
    • .view(AnyView) - custom view builder

State management pitfall

AnchoredPopup uses UIWindow to display itself above anything you might have on screen, so remember - to get adequate UI updates, use ObservableObjects or @Bindings instead of @State. This won't work:

struct MainView: View {
    @State var name = "Mike"
    var body: some View {
        Text("Show popup")
            .useAsPopupAnchor(id: "a") {
                ZStack {
                    Color.red.size(100)
                    VStack {
                        Text(name)
                        Button("Change text") {
                            name = "John"
                        }
                    }
                }
            } customize: {
                $0.position(.anchorRelative(.bottomLeading))
                    .closeOnTap(false)
            }
    }
}

This will work:

struct MainView: View {
    @State var name = "Mike"
    var body: some View {
        Text("Show popup")
            .useAsPopupAnchor(id: "a") {
                Popup(name: $name)
            } customize: {
                $0.position(.anchorRelative(.bottomLeading))
                    .closeOnTap(false)
            }
    }
}

struct Popup: View {
    @Binding var name: String
    var body: some View {
        ZStack {
            Color.red.size(100)
            VStack {
                Text(name)
                Button("Change text") {
                    name = "John"
                }
            }
        }
    }
}

This will work too:

struct MainView: View {
    var body: some View {
        Text("Show popup")
            .useAsPopupAnchor(id: "a") {
                Popup()
            } customize: {
                $0.position(.anchorRelative(.bottomLeading))
                    .closeOnTap(false)
            }
    }
}

struct Popup: View {
    @State var name = "Mike"
    var body: some View {
        ZStack {
            Color.red.size(100)
            VStack {
                Text(name)
                Button("Change text") {
                    name = "John"
                }
            }
        }
    }
}

Examples

To try AnchoredPopup examples:

  • Clone the repo https://github.com/exyte/AnchoredPopup.git
  • Open AnchoredPopupExample/AnchoredPopupExample.xcodeproj
  • Try it!

Installation

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

Requirements

  • iOS 17.0+

Our other open source SwiftUI libraries

PopupView - Toasts and popups library
Grid - The most powerful Grid container
AnimatedTabBar - A tabbar with a number of preset animations
ScalingHeaderScrollView - A scroll view with a sticky header which shrinks as you scroll
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

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages