Skip to content

Commit 85a05f6

Browse files
committed
add customizable loading screen
1 parent 10891ae commit 85a05f6

File tree

4 files changed

+161
-19
lines changed

4 files changed

+161
-19
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1510"
4+
version = "1.7">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "ErrorableView"
18+
BuildableName = "ErrorableView"
19+
BlueprintName = "ErrorableView"
20+
ReferencedContainer = "container:">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
<BuildActionEntry
24+
buildForTesting = "YES"
25+
buildForRunning = "YES"
26+
buildForProfiling = "NO"
27+
buildForArchiving = "NO"
28+
buildForAnalyzing = "YES">
29+
<BuildableReference
30+
BuildableIdentifier = "primary"
31+
BlueprintIdentifier = "ErrorableViewTests"
32+
BuildableName = "ErrorableViewTests"
33+
BlueprintName = "ErrorableViewTests"
34+
ReferencedContainer = "container:">
35+
</BuildableReference>
36+
</BuildActionEntry>
37+
</BuildActionEntries>
38+
</BuildAction>
39+
<TestAction
40+
buildConfiguration = "Debug"
41+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
42+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
43+
shouldUseLaunchSchemeArgsEnv = "YES"
44+
shouldAutocreateTestPlan = "YES">
45+
<Testables>
46+
<TestableReference
47+
skipped = "NO">
48+
<BuildableReference
49+
BuildableIdentifier = "primary"
50+
BlueprintIdentifier = "ErrorableViewTests"
51+
BuildableName = "ErrorableViewTests"
52+
BlueprintName = "ErrorableViewTests"
53+
ReferencedContainer = "container:">
54+
</BuildableReference>
55+
</TestableReference>
56+
</Testables>
57+
</TestAction>
58+
<LaunchAction
59+
buildConfiguration = "Debug"
60+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
61+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
62+
launchStyle = "0"
63+
useCustomWorkingDirectory = "NO"
64+
ignoresPersistentStateOnLaunch = "NO"
65+
debugDocumentVersioning = "YES"
66+
debugServiceExtension = "internal"
67+
allowLocationSimulation = "YES">
68+
</LaunchAction>
69+
<ProfileAction
70+
buildConfiguration = "Release"
71+
shouldUseLaunchSchemeArgsEnv = "YES"
72+
savedToolIdentifier = ""
73+
useCustomWorkingDirectory = "NO"
74+
debugDocumentVersioning = "YES">
75+
<MacroExpansion>
76+
<BuildableReference
77+
BuildableIdentifier = "primary"
78+
BlueprintIdentifier = "ErrorableView"
79+
BuildableName = "ErrorableView"
80+
BlueprintName = "ErrorableView"
81+
ReferencedContainer = "container:">
82+
</BuildableReference>
83+
</MacroExpansion>
84+
</ProfileAction>
85+
<AnalyzeAction
86+
buildConfiguration = "Debug">
87+
</AnalyzeAction>
88+
<ArchiveAction
89+
buildConfiguration = "Release"
90+
revealArchiveInOrganizer = "YES">
91+
</ArchiveAction>
92+
</Scheme>

Sources/ErrorableView/Abstract/ErrorableViewModifier.swift

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,29 @@ import SwiftUI
99

1010
public extension View {
1111
@ViewBuilder
12-
func errorableView<Content: ErrorableView>(pageState: Binding<PageStates>, @ViewBuilder content: () -> Content) -> some View {
12+
func errorableView<Content: ErrorableView, LoadingContent: LoadingView>(pageState: Binding<PageStates>,
13+
@ViewBuilder content: () -> Content,
14+
@ViewBuilder loadingContent: (() -> LoadingContent) = { DefaultLoadingView(loadingText: "Loading...") }) -> some View {
1315
self.modifier(ErrorableViewModifier(pageState: pageState) {
1416
content()
17+
} loadingContent: {
18+
loadingContent()
1519
})
1620
}
1721
}
1822

19-
public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
23+
public struct ErrorableViewModifier<ErrorContent: ErrorableView, LoadingContent: LoadingView>: ViewModifier {
2024
@State private var sheetTrigger: Bool = false
2125
@Binding var pageState: PageStates
2226
var errorContent: ErrorContent
27+
var loadingContent: LoadingContent
2328

2429
public init(pageState: Binding<PageStates>,
25-
@ViewBuilder errorContent: () -> ErrorContent) {
30+
@ViewBuilder errorContent: () -> ErrorContent,
31+
@ViewBuilder loadingContent: () -> LoadingContent) {
2632
self._pageState = pageState
2733
self.errorContent = errorContent()
34+
self.loadingContent = loadingContent()
2835
}
2936

3037
public func body(content: Content) -> some View {
@@ -44,6 +51,15 @@ public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
4451
case .failure:
4552
errorContent
4653
case .loading:
54+
switch loadingContent.type {
55+
case .onPage:
56+
loadingContent
57+
case .overlay:
58+
ZStack {
59+
content
60+
loadingContent
61+
}
62+
}
4763
DefaultLoadingView(loadingText: "Loading...")
4864
case .successful:
4965
content
@@ -56,7 +72,15 @@ public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
5672
if pageState == .successful {
5773
content
5874
} else {
59-
DefaultLoadingView(loadingText: "Loading...")
75+
switch loadingContent.type {
76+
case .onPage:
77+
loadingContent
78+
case .overlay:
79+
ZStack {
80+
content
81+
loadingContent
82+
}
83+
}
6084
}
6185
}.onChange(of: pageState) { newValue in
6286
sheetTrigger = (newValue == .failure)
@@ -72,7 +96,15 @@ public struct ErrorableViewModifier<ErrorContent: ErrorableView>: ViewModifier {
7296
if pageState == .successful {
7397
content
7498
} else {
75-
DefaultLoadingView(loadingText: "Loading...")
99+
switch loadingContent.type {
100+
case .onPage:
101+
loadingContent
102+
case .overlay:
103+
ZStack {
104+
content
105+
loadingContent
106+
}
107+
}
76108
}
77109
}.onChange(of: pageState) { newValue in
78110
sheetTrigger = (newValue == .failure)

Sources/ErrorableView/Enums/ErrorPresentTypes.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,8 @@
1010
case fullScreen
1111
case sheet
1212
}
13+
14+
@frozen public enum LoadingPresenterTypes {
15+
case onPage
16+
case overlay
17+
}

Sources/ErrorableView/Views/DefaultLoadingView.swift

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,44 @@
77

88
import SwiftUI
99

10-
@frozen public struct DefaultLoadingView: View {
10+
public protocol LoadingView: View {
11+
var type: LoadingPresenterTypes { get set }
12+
}
13+
14+
@frozen public struct DefaultLoadingView: LoadingView {
1115
var loadingText: LocalizedStringKey
1216
var progressViewColor: Color
17+
public var type: LoadingPresenterTypes
1318

1419
public init(loadingText: LocalizedStringKey,
15-
progressViewColor: Color = .accentColor
20+
progressViewColor: Color = .accentColor,
21+
type: LoadingPresenterTypes = .overlay
1622
) {
1723
self.loadingText = loadingText
1824
self.progressViewColor = progressViewColor
25+
self.type = type
1926
}
2027

2128
public var body: some View {
22-
VStack {
23-
if #available(iOS 15.0, *) {
24-
ProgressView()
25-
.scaleEffect(1.2)
26-
.tint(progressViewColor)
27-
} else {
28-
ProgressView()
29-
.scaleEffect(1.2)
29+
ZStack {
30+
Rectangle()
31+
.foregroundColor(.red)
32+
.ignoresSafeArea()
33+
.opacity(type == .onPage ? 1 : 0.3)
34+
VStack {
35+
if #available(iOS 15.0, *) {
36+
ProgressView()
37+
.scaleEffect(1.2)
38+
.tint(progressViewColor)
39+
} else {
40+
ProgressView()
41+
.scaleEffect(1.2)
42+
}
43+
Text(loadingText)
44+
.font(.caption)
45+
.foregroundColor(.secondary)
46+
.padding(.top)
3047
}
31-
Text(loadingText)
32-
.font(.caption)
33-
.foregroundColor(.secondary)
34-
.padding(.top)
3548
}
3649
}
3750
}

0 commit comments

Comments
 (0)