Skip to content

Commit

Permalink
增加了 Swift 6 兼容性支持
Browse files Browse the repository at this point in the history
增加了 queryView 功能
  • Loading branch information
fatbobman committed Apr 16, 2024
1 parent 151b788 commit 4ba8271
Show file tree
Hide file tree
Showing 27 changed files with 334 additions and 37 deletions.
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1530"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "SwiftUIOverlayContainer"
BuildableName = "SwiftUIOverlayContainer"
BlueprintName = "SwiftUIOverlayContainer"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "SwiftUIOverlayContainerTests"
BuildableName = "SwiftUIOverlayContainerTests"
BlueprintName = "SwiftUIOverlayContainerTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "SwiftUIOverlayContainer"
BuildableName = "SwiftUIOverlayContainer"
BlueprintName = "SwiftUIOverlayContainer"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "E8B0B5CD-BB78-4F9E-86E6-96E2C76C798B"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "00FC7129-C0C0-428E-B885-389AB000E4BE"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Sources/SwiftUIOverlayContainer/ContainerManager/ContainerManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "99"
endingLineNumber = "99"
landmarkName = "createPublisher(for:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "10104EFD-C213-4812-AD64-291BFBCDC114"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Sources/SwiftUIOverlayContainer/ContainerManager/ContainerManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "130"
endingLineNumber = "130"
landmarkName = "_show(view:with:in:using:isPresented:animated:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "329034B1-3198-4A21-BF0F-ECEEB2526626"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Sources/SwiftUIOverlayContainer/ContainerManager/ContainerManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "120"
endingLineNumber = "120"
landmarkName = "_show(view:with:in:using:isPresented:animated:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>SwiftUIOverlayContainer-Package.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>SwiftUIOverlayContainer.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>SwiftUIOverlayContainer</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>SwiftUIOverlayContainerTests</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "0A3F0EB0-7747-4252-A57C-05A1B711BDCA"
type = "1"
version = "2.0">
</Bucket>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Demo (iOS).xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>Demo (macOS).xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
</dict>
</plist>
7 changes: 5 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.5
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down Expand Up @@ -27,7 +27,10 @@ let package = Package(
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "SwiftUIOverlayContainer",
dependencies: []
dependencies: [],
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency"),
]
),
.testTarget(
name: "SwiftUIOverlayContainerTests",
Expand Down
1 change: 1 addition & 0 deletions Sources/SwiftUIOverlayContainer/Container/Container.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct SwiftUIOverlayContainerModifier: ViewModifier {
/// The SwiftUI overlay container view.
///
/// Receive the command from container manager, show or dismiss views according the configuration
@MainActor
struct OverlayContainer: View {
/// Container configuration
let configuration: ContainerConfigurationProtocol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,8 @@ public protocol ContainerConfigurationProtocol: ContainerViewConfigurationProtoc
& ContainerTypeConfigurationProtocol
& ContainerCompositionProtocol
& ContainerQueueControlProtocol {}

/// A Query Type for get specific container's queue
public class IdentifiableContainerViewQuery {
var views:[IdentifiableContainerView] = []
}
4 changes: 2 additions & 2 deletions Sources/SwiftUIOverlayContainer/Container/ContainerType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation
import SwiftUI

/// The display type of the container view, this type will determine the layout of the container
public enum ContainerViewDisplayType {
public enum ContainerViewDisplayType: Sendable {
/// The views are arranged horizontally. Normally (spacing is greater than 0), views do not overlap each other. Internal implementation uses HStack.
///
/// In horizontal mode, all views share a single background
Expand All @@ -29,7 +29,7 @@ public enum ContainerViewDisplayType {
}

/// The view queue type of the container. This type will determine if multiple views are allowed to exist in the container at the same time
public enum ContainerViewQueueType {
public enum ContainerViewQueueType: Sendable {
/// Only one view can be displayed at a time. When the container receives a new view, the current view will be dismissed and the new view will be displayed.
case oneByOne
/// Only one view can be displayed at a time. A new view needs to wait until the current view is dismissed (close call dismiss code, Binding value, auto dismiss, etc.) before it can be displayed.
Expand Down
16 changes: 15 additions & 1 deletion Sources/SwiftUIOverlayContainer/Container/QueueHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ extension ContainerQueueHandler {
dismissMainQueue(animated: animated)
case let .dismissTopmostView(animated):
dismissTopmostView(animated: animated)
case let .viewQuery(containerName, query):
if containerName == container {
query.views = mainQueue + tempQueue
}
}
}

Expand All @@ -296,6 +300,10 @@ extension ContainerQueueHandler {
dismissMainQueue(animated: animated)
case let .dismissTopmostView(animated):
dismissTopmostView(animated: animated)
case let .viewQuery(containerName, query):
if containerName == container {
query.views = mainQueue + tempQueue
}
}
}

Expand All @@ -319,6 +327,10 @@ extension ContainerQueueHandler {
dismissMainQueue(animated: animated)
case let .dismissTopmostView(animated):
dismissTopmostView(animated: animated)
case let .viewQuery(containerName, query):
if containerName == container {
query.views = mainQueue + tempQueue
}
}
}

Expand All @@ -336,11 +348,13 @@ extension ContainerQueueHandler {
_transferring = false
return
}
delayToRun(seconds: seconds) {
Task { @MainActor in
await delayToRun(seconds: seconds) {
guard let view = self.tempQueue.first else { return }
self.tempQueue.removeFirst()
self._transferring = false
self.pushViewIntoQueue(view, queue: .main)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation
import SwiftUI

struct ViewFrameKey: PreferenceKey {
static var defaultValue: CGRect = .zero
static let defaultValue: CGRect = .zero
static func reduce(value: inout CGRect, nextValue: () -> CGRect) {}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ enum OverlayContainerAction {
///
/// Pass false to disable animation of transition
case dismissTopmostView(Bool)
/// Get specific container's view queue
///
/// Pass container's name and a IdentifiableContainerViewQuery instance
case viewQuery(String, IdentifiableContainerViewQuery)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import SwiftUI
/// }
///
/// Because the Container Manager adopts the singleton pattern, you can directly call public methods such as show and dismiss through code even if you are not in the SwiftUI view.
public final class ContainerManager: ContainerManagerLogger {
public final class ContainerManager: ContainerManagerLogger, @unchecked Sendable {
var publishers: [String: ContainerViewPublisher] = [:]

public init(logger: SwiftUIOverlayContainerLoggerProtocol? = nil, debugLevel: Int = 0) {
Expand Down Expand Up @@ -228,6 +228,18 @@ extension ContainerManager: ContainerViewManagementForEnvironment {
}
}
}

/// Query a specific container's queue
///
/// A very brief wait is required, even if it's only 0.01 seconds, otherwise the result cannot be obtained.
/// - Parameters:
/// - container: container name
/// - queryResult: a IdentifiableContainerViewQuery instance
public func queryViews(in container: String, queryResult: IdentifiableContainerViewQuery ) {
if let publisher = getPublisher(for: container) {
publisher.upstream.send(.viewQuery(container, queryResult))
}
}
}

public extension ContainerManager {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,10 @@ extension View {
func autoDismiss(_ type: ContainerViewAutoDismiss, dismissAction: @escaping DismissAction) -> some View {
if case .seconds(let timeInterval) = type {
self
.task {
.task { @MainActor in
try? await Task.sleep(seconds: timeInterval)
if !Task.isCancelled {
await MainActor.run {
dismissAction()
}
dismissAction()
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import Foundation
import SwiftUI

typealias DismissAction = () -> Void
typealias DismissAction = @MainActor @Sendable () -> Void

/// A configuration protocol for container and container view
public protocol ContainerViewConfigurationProtocol {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extension ContainerViewDismissGesture {
///
/// The dismiss Action not only includes the cancellation action of Overlay Container view,
/// but also the dismiss closure specified by user
@MainActor
func generateGesture(with dismissAction: @escaping DismissAction) -> AnyGesture<Void>? {
// only support longPress in tvOS
#if os(tvOS)
Expand Down Expand Up @@ -169,6 +170,7 @@ extension View {
/// .dismissGesture(gestureType:gesture, dismissAction: some action)
///
@ViewBuilder
@MainActor
func dismissGesture(gestureType: ContainerViewDismissGesture, dismissAction: @escaping () -> Void) -> some View {
if let gesture = gestureType.generateGesture(with: dismissAction) {
self.gesture(gesture)
Expand Down
Loading

0 comments on commit 4ba8271

Please sign in to comment.