• Stars
    star
    335
  • Rank 125,904 (Top 3 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 4 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

SwiftUI Overlay Container is a view container component for SwiftUI. It is a customizable, efficient and convenient view manager.

SwiftUI Overlay Container 2

A highly customizable view container components for SwiftUI

os swift

中文版说明

Table of Contents

Overview

SwiftUI Overlay Container is a view container component for SwiftUI. It is a customizable, efficient and convenient view manager.

With just a simple configuration, SwiftUI Overlay Container can do the basic work of view organization, queue handling, transitions, animations, interactions, display style configuration and so on for you, allowing developers to devote more effort to the implementation of the application view itself.

Motivation

When we need to display new content in the upper layer of the view (for example: pop-up information, side menu, help tips, etc.), there are many excellent third-party solutions that can help us achieve it separately, but no solution can deal with different at the same time.

In SwiftUI, describing views has become very easy, so we can completely extract the display logic in the above scenarios, create a library that can cover more usage scenarios, and help developers organize the display style and interaction logic of views .

Features

  • Multiple container support
  • Supports multiple views within a single container
  • Push views to any specified container within or outside of SwiftUI view code
  • The configuration of the container can be modified dynamically (except for queue type and clipped)
  • Views inside a container can be arranged in multiple ways
  • There are multiple queue types to guide the container on how to display the view

Quick Guide

For more details, see the demo in the library and the comments in the source code.

Create a container

Create a view container on top of the specified view with the same dimensions as the view it is attached to.

VStack{
    // your view
}
.overlayContainer("containerA", containerConfiguration: AConfiguration())

When no view container is required to be attached to a view.

ViewContainer("containerB", configuration: BConfiguration())

Show views in containers

Display the view MessageView in the view container containerA

.containerView(in: "containerA", configuration: ViewConfiguration(), isPresented: $show, content: MessageView())

Use the container manager

struct ContentView1: View {
    @Environment(\.overlayContainerManager) var manager
    var body: some View {
        VStack {
            Button("push view in containerB") {
                manager.show(view: MessageView(), in: "containerB", using: ViewConfiguration())
            }
        }
    }
}

Dismiss all views in the specified container

struct ContentView1: View {
    @Environment(\.overlayContainerManager) var manager
    var body: some View {
        VStack {
            Button("push view in containerB") {
                manager.dismissAllView(in: ["containerA","containerB"], animated: true)
            }
        }
    }
}

Knowledge

Container

The component that receives and displays the view. At least for the container you need to set: name, view display type, view queue type.

You can set the default view style for the container, and for style properties not specified by the view, the container's default settings will be used instead.

Display type

  • stacking

    When multiple views are displayed in the container at the same time, the views are arranged along the Z axis. It behaves like ZStack.

    stacking

  • horizontal

    When multiple views are displayed in the container at the same time, the views are arranged along the X axis. It behaves like HStack.

    horizontal

  • vertical

    When multiple views are displayed in the container at the same time, the views are arranged along the Y axis. It behaves like VStack.

    vertical

Queue Type

  • multiple

    Multiple views can be displayed within a container at the same time. When the given number of views exceeds the maximum number of views set by the container, the excess views will be temporarily stored in the waiting queue, and will be replenished one by one after the displayed views are dismissed.

    multiple

  • oneByOne

    Only one view can be displayed in the container at the same time. The newly added view will automatically replace the one being displayed.

    oneByOne

  • oneByOneWaitFinish

    One view can be displayed in the container at the same time. Only after the currently displayed view is dismissed, the new view can be displayed.

    oneByOneWaitFinish

Configuring the container

The configuration of the container must set at least the following properties:

struct MyContainerConfiguration:ContainerConfigurationProtocol{
    var displayType: ContainerViewDisplayType = .stacking
    var queueType: ContainerViewQueueType = .multiple
}

Other properties:

  • delayForShowingNext

    Time interval to replenish the next view

  • maximumNumberOfViewsInMultipleMode

    The maximum number of views that can be displayed simultaneously in the container in multiple mode

  • spacing

    Spacing between views in vertical and horizontal modes

  • insets

    In stacking mode, the value is an insets value of the view. In horizontal and vertical mode, the value is an insets value of the view group

  • clipped

    Clipping the container, set to true when you want to limit the bounds of the view transition

  • ignoresSafeArea

    Expending the container out of it's safe area. The default value is .disable (do not ignore), .all (ignore all safe area) and .custom (customize regions and edges)

  • queueControlOperator

    Execute the window operation only after the specified time interval has elapsed,default is none,that is, not enabled

    It is only applicable to special needs scenarios, such as using OverallContainer instead of Sheet.In a List, clicking each row will pop up a window. In this case, if the user accidentally uses multiple fingers to click, it will open multiple window condition.Enable the debounce function for the container, and the container will only retain one valid operation in a short period of time. Usually just set the duetime to 0.1 seconds( .debounce(seconds: 0.1) )

  • Configuration for all other container views (used as defaults for container views)

    See Configuring Container Views below for details

The EnvironmentValue of container

Each container provides an environment value - overlayContainer for the view inside the container. The view inside the container can obtain the container's information (name, size, display type, queue type) through this value and perform the behavior of dismissing itself.

struct MessageView: View {
    @Environment(\.overlayContainer) var container
    var body: some View {
        RoundedRectangle(cornerRadius: 10)
            .frame(width: 300, height: 10)
            .overlay(
                HStack {
                    Text("container Name:\(container.containerName)")
                    Button("Dismiss me"){
                        container.dismiss()
                    }
                }
            )
    }
}

Container view

All SwiftUI views can be displayed inside a container. You can create the same view configuration for similar functional views, or make a specific view conform to the ContainerViewConfigurationProtocol protocol and set it separately.

Configuring the container view

public protocol ContainerViewConfigurationProtocol {
    var alignment: Alignment? { get }
    var tapToDismiss: Bool? { get }
    var backgroundStyle: ContainerBackgroundStyle? { get }
    var backgroundTransitionStyle: ContainerBackgroundTransitionStyle { get }
    var shadowStyle: ContainerViewShadowStyle? { get }
    var dismissGesture: ContainerViewDismissGesture? { get }
    var transition: AnyTransition? { get }
    var autoDismiss: ContainerViewAutoDismiss? { get }
    var disappearAction: (() -> Void)? { get }
    var appearAction: (() -> Void)? { get }
    var animation: Animation? { get }
}
  • alignment

    Sets the alignment of the view or view group within the container. In stacking mode, you can set a different alignment for each view, and in vertical or horizontal mode, all views (view groups) share the container's alignment settings.

  • tapToDismiss

    Whether to allow the view to be dismissed by clicking on the background if the backgroundStyle is set for the view.

    See the project demo code for details

  • backgroundStyle

    Set the background for the container view. Currently supports color, blur, customView.

    Some versions of operating systems (iOS 14, watchOS) do not support blur mode. If you want to use blur in these versions, you can wrap other blur codes through customView.

    See the project demo code for details

    background

  • backgroundTransitionStyle

    background transitions. Default is opacity, set to identity to cancel the transition.

  • shadowStyle

    Add shadow to view

  • dismissGesture

    Add a cancel gesture to the view, currently supports single tap, double tap, long press, swipe left, swipe right, swipe up, swipe down, and custom gesture.

    Use eraseToAnyGestureForDismiss to erase the type when using custom gestures.

    let gesture = LongPressGesture(minimumDuration: 1, maximumDistance: 5).eraseToAnyGestureForDismiss()

    Under tvOS, only long press are supported

    See the project demo code for details

    gesture

  • transition

    Transition of view

  • animation

    The animation of the view transitions

  • autoDismiss

    Whether to support automatic dismissing. .seconds(3) means that the view will be automatically dismissed after 3 seconds.

    See the project demo code for details

  • disappearAction

    Closure that executes after the view is dismissed

  • appearAction

    Closure that executes before the view is displayed in the container

Container Manager

The container manager is the bridge between the program code and the container. By calling specific methods of the container manager, the user allows the specified container to perform tasks such as displaying a view, dismissing a view, etc.

The EnvironmentValue of container manager

In SwiftUI, the view code calls the container manager through the environment value.

struct ContentView1: View {
    @Environment(\.overlayContainerManager) var manager
    var body: some View {
        VStack {
            Button("push view in containerB") {
                manager.show(view: MessageView(), in: "containerB", using: ViewConfiguration())
            }
        }
    }
}

The methods currently provided by the Container Manager are.

  • show(view: Content, with ID: UUID?, in container: String, using configuration: ContainerViewConfigurationProtocol, animated: Bool) -> UUID?

    Show the view in the specified container, the return value is the ID of the view

  • dismiss(view id: UUID, in container: String, animated flag: Bool)

    Dismiss the view with the specified ID In the specified container,

  • dismissAllView(notInclude excludeContainers: [String], onlyShowing: Bool, animated flag: Bool)

    Dismisses views in all containers except the specified container. When onlyShow is true, only the view that is being displayed is dismissed.

  • dismissAllView(in containers: [String], onlyShowing: Bool, animated flag: Bool)

    Dismiss all views in the specified containers

  • dismissTopmostView(in containers: [String], animated flag: Bool)

    Dismiss the top view in specified containers

Blockable animation

The transition animation can be forced to cancel when animated is set to false, either by calling the container manager directly or by using a View modifier.

This is useful when dealing with scenarios such as Deep Link.

animation

Use outside of SwiftUI views

If you want to call the container manager outside of a SwiftUI view, you can call the ContainerManager singleton directly:

let manager = ContainerManager.share
manager.show(view: MessageView(), in: "containerB", using: ViewConfiguration())

System Requirements

  • iOS 14+
  • macOS 11+
  • tvOS 14+
  • watchOS 7+

Installation

The preferred way to install SwiftUIOverlayContainer is through the Swift Package Manager.

dependencies: [
  .package(url: "https://github.com/fatbobman/SwiftUIOverlayContainer.git", from: "2.0.0")
]

Copyrights

This library is released under the MIT license. See LICENSE for details.

Help and Support

You can give your feedback or suggestions by creating Issues. You can also contact me on Twitter @fatbobman.

More Repositories

1

SwipeCell

SwipeCell is a SwiftUI library, used to achieve the left and right sliding menu effect similar to the iOS mail app.
Swift
294
star
2

NavigationViewKit

NavigationViewKit is a NavigationView extension library for SwiftUI.
Swift
113
star
3

SheetKit

an extension library for SwiftUI sheets.
Swift
100
star
4

Infinite4Pager

Infinite4Pager is a flexible and powerful SwiftUI component that provides infinite scrolling capabilities in four directions: up, down, left, and right. It's perfect for creating image galleries, card decks, or any other content that requires seamless navigation in multiple directions.
Swift
98
star
5

BlogCodes

【肘子的Swift笔记】博文中的代码汇总
Swift
98
star
6

SwiftDataKit

SwiftDataKit allows SwiftData developers to access Core Data objects corresponding to SwiftData elements.
Swift
92
star
7

PersistentHistoryTrackingKit

A library for managing Core Data's Persistent History Tracking
Swift
82
star
8

IsScrolling

As the name suggests, IsScrolling provides a ViewModifier to get the current scrolling state of a ScrollView or List in SwiftUI. IsScrolling has good backward and forward compatibility since it is fully implemented natively in SwiftUI. 正如名称所示,IsScrolling 提供了一个 ViewModifier ,用来获取 SwiftUI 中 ScrollView 或 List 当前的滚动状态。由于完全采用了 SwiftUI 原生的方式实现此功能,因此 IsScrolling 具备了很好的前后兼容性。
Swift
74
star
9

MovieHunter

Swift
43
star
10

ShareData_Demo_For_CoreDataWithCloudKit

Demo for wwdc21-10015,how to share data by Core Data with CloudKit
Swift
29
star
11

Todo

Swift
23
star
12

PublishThemeForFatbobmanBlog

A publish theme and plugin for fatbobman.com.Plugins:TruncateHtmlDescription.TagCount,,Bilibili Video,RssPropertiesSetting and more...
Swift
22
star
13

ObservableDefaults

A Swift library that integrates UserDefaults with the new SwiftUI Observation framework
Swift
19
star
14

CoreDataEvolution

A library aimed at modernizing Core Data by incorporating the elegance and safety of SwiftData-style concurrency.
Swift
17
star
15

SwiftDataConcurrencyDemo

Swift
17
star
16

DismissConfirmSheet

iOS14 multiSheet solution. Includes dismiss gesture control
Swift
14
star
17

MOCloner

A tiny library that implements deep copy of NSManagedObject
Swift
10
star
18

TextFieldFomatAndValidateDemo

Swift
9
star
19

PersistentHistoryTrackingDemo

Persistent History Tracking Demo
Swift
9
star
20

ListExample

SwiftUI List example
Swift
7
star
21

CommandExample

SwiftUI 2.0 Commands example
Swift
3
star
22

SimpleLogger

A simple logging library for Swift 6, providing easy-to-use logging functionalities with support for different log levels and backends.
Swift
2
star
23

SwiftIODemo

Swift
2
star
24

MySingleSoureOfTruthDemo

Swift
2
star
25

local-search-engine-for-Publish

local-search-engine-for-publish
Swift
2
star
26

fatbobman.github.io

HTML
2
star
27

SingleStoreDemo

Swift
2
star
28

ModelActorX

ModelActorX is a Swift library that provides custom macros ModelActorX and MainModelActorX to enhance and extend the functionality of SwiftData's ModelActor.
Swift
1
star
29

ShareCode

Some code snippets for sharing 一些用于分享的代码片段
Swift
1
star
30

blogComments

1
star
31

AstroRSSIssue

Astro
1
star
32

FatBlog

CSS
1
star
33

CoreDataInPreview

演示如何为SwiftUI的Preview提供Core Data数据
Swift
1
star
34

LocalizationDemoForBlogPost

Swift
1
star
35

CustomParseableFormatStyleDemo

Swift
1
star