Skip to content

Commit

Permalink
add customizable loading screen
Browse files Browse the repository at this point in the history
  • Loading branch information
devmehmetates committed May 2, 2024
1 parent 10891ae commit 85a05f6
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 19 deletions.
92 changes: 92 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/ErrorableView.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ErrorableView"
BuildableName = "ErrorableView"
BlueprintName = "ErrorableView"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ErrorableViewTests"
BuildableName = "ErrorableViewTests"
BlueprintName = "ErrorableViewTests"
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 = "ErrorableViewTests"
BuildableName = "ErrorableViewTests"
BlueprintName = "ErrorableViewTests"
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 = "ErrorableView"
BuildableName = "ErrorableView"
BlueprintName = "ErrorableView"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
42 changes: 37 additions & 5 deletions Sources/ErrorableView/Abstract/ErrorableViewModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,29 @@ import SwiftUI

public extension View {
@ViewBuilder
func errorableView<Content: ErrorableView>(pageState: Binding<PageStates>, @ViewBuilder content: () -> Content) -> some View {
func errorableView<Content: ErrorableView, LoadingContent: LoadingView>(pageState: Binding<PageStates>,
@ViewBuilder content: () -> Content,
@ViewBuilder loadingContent: (() -> LoadingContent) = { DefaultLoadingView(loadingText: "Loading...") }) -> some View {
self.modifier(ErrorableViewModifier(pageState: pageState) {
content()
} loadingContent: {
loadingContent()
})
}
}

public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
public struct ErrorableViewModifier<ErrorContent: ErrorableView, LoadingContent: LoadingView>: ViewModifier {
@State private var sheetTrigger: Bool = false
@Binding var pageState: PageStates
var errorContent: ErrorContent
var loadingContent: LoadingContent

public init(pageState: Binding<PageStates>,
@ViewBuilder errorContent: () -> ErrorContent) {
@ViewBuilder errorContent: () -> ErrorContent,
@ViewBuilder loadingContent: () -> LoadingContent) {
self._pageState = pageState
self.errorContent = errorContent()
self.loadingContent = loadingContent()
}

public func body(content: Content) -> some View {
Expand All @@ -44,6 +51,15 @@ public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
case .failure:
errorContent
case .loading:
switch loadingContent.type {
case .onPage:
loadingContent
case .overlay:
ZStack {
content
loadingContent
}
}
DefaultLoadingView(loadingText: "Loading...")
case .successful:
content
Expand All @@ -56,7 +72,15 @@ public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
if pageState == .successful {
content
} else {
DefaultLoadingView(loadingText: "Loading...")
switch loadingContent.type {
case .onPage:
loadingContent
case .overlay:
ZStack {
content
loadingContent
}
}
}
}.onChange(of: pageState) { newValue in
sheetTrigger = (newValue == .failure)
Expand All @@ -72,7 +96,15 @@ public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
if pageState == .successful {
content
} else {
DefaultLoadingView(loadingText: "Loading...")
switch loadingContent.type {
case .onPage:
loadingContent
case .overlay:
ZStack {
content
loadingContent
}
}
}
}.onChange(of: pageState) { newValue in
sheetTrigger = (newValue == .failure)
Expand Down
5 changes: 5 additions & 0 deletions Sources/ErrorableView/Enums/ErrorPresentTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@
case fullScreen
case sheet
}

@frozen public enum LoadingPresenterTypes {
case onPage
case overlay
}
41 changes: 27 additions & 14 deletions Sources/ErrorableView/Views/DefaultLoadingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,44 @@

import SwiftUI

@frozen public struct DefaultLoadingView: View {
public protocol LoadingView: View {
var type: LoadingPresenterTypes { get set }
}

@frozen public struct DefaultLoadingView: LoadingView {
var loadingText: LocalizedStringKey
var progressViewColor: Color
public var type: LoadingPresenterTypes

public init(loadingText: LocalizedStringKey,
progressViewColor: Color = .accentColor
progressViewColor: Color = .accentColor,
type: LoadingPresenterTypes = .overlay
) {
self.loadingText = loadingText
self.progressViewColor = progressViewColor
self.type = type
}

public var body: some View {
VStack {
if #available(iOS 15.0, *) {
ProgressView()
.scaleEffect(1.2)
.tint(progressViewColor)
} else {
ProgressView()
.scaleEffect(1.2)
ZStack {
Rectangle()
.foregroundColor(.red)
.ignoresSafeArea()
.opacity(type == .onPage ? 1 : 0.3)
VStack {
if #available(iOS 15.0, *) {
ProgressView()
.scaleEffect(1.2)
.tint(progressViewColor)
} else {
ProgressView()
.scaleEffect(1.2)
}
Text(loadingText)
.font(.caption)
.foregroundColor(.secondary)
.padding(.top)
}
Text(loadingText)
.font(.caption)
.foregroundColor(.secondary)
.padding(.top)
}
}
}
Expand Down

0 comments on commit 85a05f6

Please sign in to comment.