Skip to content

Commit 5dc37bb

Browse files
committed
📝 :: Update documentation
1 parent cfa7961 commit 5dc37bb

2 files changed

Lines changed: 351 additions & 254 deletions

File tree

README.md

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
# Gradient Loading Bar
2+
3+
![Swift6.2](https://img.shields.io/badge/Swift-6.2-green.svg?style=flat) ![CI Status](https://img.shields.io/github/actions/workflow/status/fxm90/GradientLoadingBar/continuous-integration.yml?branch=feature/version-4) ![Code Coverage](https://img.shields.io/codecov/c/github/fxm90/GradientLoadingBar.svg?style=flat) ![Version](https://img.shields.io/github/v/release/fxm90/GradientLoadingBar) ![License](https://img.shields.io/github/license/fxm90/GradientLoadingBar?color=333333) ![Platform](https://img.shields.io/badge/platform-iOS-8a8a8a)
4+
5+
A customizable animated gradient loading bar, with full support for **SwiftUI** and **UIKit**.\
6+
Inspired by [iOS 7 Progress Bar on Codepen](https://codepen.io/marcobiedermann/pen/LExXWW).
7+
8+
### Screenshot
9+
10+
![Example][example]
11+
12+
To run the example project, clone this repository and open the project file from the **Example** directory.
13+
14+
## Requirements
15+
16+
- Swift **6.2**
17+
- Xcode **26**
18+
- iOS **26.0+**
19+
20+
### Compatibility Notes
21+
22+
- **iOS < 26.0 / CocoaPods / Carthage support**
23+
Use version **`3.x.x`**
24+
- **iOS < 13.0 support**
25+
Use version **`2.x.x`**
26+
27+
## Installation
28+
29+
### Swift Package Manager
30+
31+
**Gradient Loading Bar** is distributed via **Swift Package Manager (SPM)**. Add it to your Xcode project as a package dependency or adapt your `Package.swift` file.
32+
33+
#### Option 1: Xcode
34+
35+
1. Open your project in **Xcode**
36+
2. Go to **File → Add Packages…**
37+
3. Enter the package URL: `https://github.com/fxm90/GradientLoadingBar`
38+
4. Choose the version rule (e.g. _Up to Next Major_ starting at **4.0.0**)
39+
5. Add the package to your target
40+
41+
#### Option 2: `Package.swift`
42+
43+
If you manage dependencies manually, add this repository to the `dependencies` section of your `Package.swift`:
44+
45+
```swift
46+
dependencies: [
47+
.package(
48+
url: "https://github.com/fxm90/GradientLoadingBar",
49+
from: "4.0.0"
50+
)
51+
]
52+
```
53+
54+
Then reference the product in your target configuration:
55+
56+
```swift
57+
.product(
58+
name: "GradientLoadingBar",
59+
package: "GradientLoadingBar"
60+
)
61+
```
62+
63+
Once the package is added, import the framework where needed:
64+
65+
```swift
66+
import GradientLoadingBar
67+
```
68+
69+
## Overview
70+
71+
This framework provides four classes:
72+
73+
- **[`GradientLoadingBar`](#gradientloadingbar)**\
74+
A controller class, managing the visibility of the `GradientActivityIndicatorView` attached to the current key window.
75+
76+
- **[`NotchGradientLoadingBar`](#notchgradientloadingbar)**\
77+
A subclass of `GradientLoadingBar`, wrapping the `GradientActivityIndicatorView` around the iPhone notch.
78+
79+
- **[`GradientActivityIndicatorView`](#gradientactivityindicatorview)**\
80+
A `UIView` containing the gradient with the animation.
81+
82+
- **[`GradientLoadingBarView`](#gradientloadingbarview)**\
83+
A SwiftUI `View` containing the gradient with the animation.
84+
85+
## GradientLoadingBar
86+
87+
`GradientLoadingBar` is a controller-style object that manages a gradient loading bar attached to the app’s key window.
88+
89+
### Basic Usage
90+
91+
Store an instance as a property (e.g. on your view controller) and control the visibility using `fadeIn()` and `fadeOut()`.
92+
93+
```swift
94+
final class UserProfileViewController: UIViewController {
95+
96+
private let gradientLoadingBar = GradientLoadingBar()
97+
98+
// ...
99+
100+
override func viewDidLoad() {
101+
super.viewDidLoad()
102+
103+
gradientLoadingBar.fadeIn()
104+
105+
userProfileService.fetchUserProfile { [weak self] _ in
106+
// ...
107+
// Be sure to call this on the main actor!
108+
self?.gradientLoadingBar.fadeOut()
109+
}
110+
}
111+
}
112+
```
113+
114+
If the loading bar needs to be accessed from multiple locations in your codebase, use the shared instance provided by the static property `GradientLoadingBar.shared`.
115+
This instance can be overridden to customize the loading bar globally.
116+
117+
### Configuration
118+
119+
```swift
120+
let gradientLoadingBar = GradientLoadingBar(
121+
height: 5.0,
122+
isRelativeToSafeArea: false,
123+
)
124+
125+
gradientLoadingBar.gradientColors = [.red, .white, .blue]
126+
gradientLoadingBar.progressAnimationDuration = 4.5
127+
```
128+
129+
#### Parameters
130+
131+
- **`height: CGFloat`**\
132+
Sets the bar height (default: `3.0`)
133+
134+
- **`isRelativeToSafeArea: Bool`**\
135+
Determines whether the bar is positioned relative to the safe area (default: `true`)
136+
137+
| Relative To Safe Area | Ignoring Safe Area |
138+
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
139+
| [![Relative to Safe Area][relative-to-safe-area-thumbnail]][relative-to-safe-area] | [![Ignoring Safe Area][ignoring-safe-area-thumbnail]][ignoring-safe-area] |
140+
141+
The gradient animation is easier to see in a video of the example application:
142+
143+
<details>
144+
<summary>🎬 Relative To Safe Area</summary>
145+
146+
https://github.com/user-attachments/assets/c8a3a117-c164-49f5-9511-aa29b92b5344
147+
</details>
148+
149+
<details>
150+
<summary>🎬 Ignoring Safe Area</summary>
151+
152+
https://github.com/user-attachments/assets/4abad13d-e019-43b3-b3b3-c874ac8f9224
153+
</details>
154+
155+
**Note:** For a third option — wrapping around the iPhone notch — see `NotchGradientLoadingBar`.
156+
157+
#### Properties
158+
159+
- **`gradientColors: [UIColor]`**\
160+
Defines the gradient colors.
161+
162+
- **`progressAnimationDuration: TimeInterval`**\
163+
Controls how fast the gradient animates from left to right.
164+
165+
#### Methods
166+
167+
- **`fadeIn(duration: TimeInterval = 0.33, completion: ((Bool) -> Void)? = nil)`**\
168+
Fades the loading bar in.
169+
170+
- **`fadeOut(duration: TimeInterval = 0.66, completion: ((Bool) -> Void)? = nil)`**\
171+
Fades the loading bar out.
172+
173+
## NotchGradientLoadingBar
174+
175+
`NotchGradientLoadingBar` is a subclass of `GradientLoadingBar` that wraps the bar around the iPhone notch.\
176+
On devices without a notch, it behaves identically to `GradientLoadingBar`.
177+
178+
| iPhone 12 Pro | iPhone 13 Pro Max |
179+
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
180+
| [![iPhone 12 Pro][notch-iphone-12-pro-thumbnail]][notch-iphone-12-pro] | [![iPhone 13 Pro Max][notch-iphone-13-pro-max-thumbnail]][notch-iphone-13-pro-max] |
181+
182+
The gradient animation is easier to see in a video of the example application:
183+
184+
<details>
185+
<summary>🎬 iPhone 12 Pro</summary>
186+
187+
https://github.com/user-attachments/assets/998fe36c-40c5-4c70-9ce8-e7a7f3f126d8
188+
</details>
189+
190+
<details>
191+
<summary>🎬 iPhone 13 Pro Max</summary>
192+
193+
https://github.com/user-attachments/assets/2ff6d717-07f1-4d70-887e-2727d55f2515
194+
</details>
195+
196+
## GradientActivityIndicatorView
197+
198+
If you prefer direct view composition, `GradientActivityIndicatorView` is a `UIView` subclass that can be added to other views — such as `UINavigationBar`, `UIButton` or a custom container.
199+
200+
### Basic Usage
201+
202+
Store an instance as a property, set-up constraints and control the visibility using `fadeIn()` and `fadeOut()`.
203+
204+
```swift
205+
final class UserProfileViewController: UIViewController {
206+
207+
private let gradientActivityIndicatorView = GradientActivityIndicatorView()
208+
209+
// ...
210+
211+
override func viewDidLoad() {
212+
super.viewDidLoad()
213+
214+
gradientActivityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
215+
view.addSubview(gradientActivityIndicatorView)
216+
217+
NSLayoutConstraint.activate([
218+
gradientActivityIndicatorView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
219+
gradientActivityIndicatorView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
220+
gradientActivityIndicatorView.topAnchor.constraint(equalTo: view.topAnchor),
221+
gradientActivityIndicatorView.heightAnchor.constraint(equalToConstant: 3),
222+
])
223+
224+
gradientActivityIndicatorView.fadeIn()
225+
226+
userProfileService.fetchUserProfile { [weak self] _ in
227+
// ...
228+
// Be sure to call this on the main actor!
229+
self?.gradientActivityIndicatorView.fadeOut()
230+
}
231+
}
232+
}
233+
```
234+
235+
### Configuration
236+
237+
```swift
238+
let gradientActivityIndicatorView = GradientActivityIndicatorView()
239+
gradientActivityIndicatorView.gradientColors = [.red, .white, .blue]
240+
gradientActivityIndicatorView.progressAnimationDuration = 4.5
241+
```
242+
243+
#### Properties
244+
245+
- **`isHidden: Bool`**\
246+
Toggles the view visibility and starts / stops the progress animation accordingly.
247+
248+
- **`gradientColors: [UIColor]`**\
249+
Defines the gradient colors.
250+
251+
- **`progressAnimationDuration: TimeInterval`**\
252+
Controls how fast the gradient animates from left to right.
253+
254+
#### Methods
255+
256+
- **`fadeIn(duration: TimeInterval = 0.33, completion: ((Bool) -> Void)? = nil)`**\
257+
Fades the view in.
258+
259+
- **`fadeOut(duration: TimeInterval = 0.66, completion: ((Bool) -> Void)? = nil)`**\
260+
Fades the view out.
261+
262+
- **`animate(isHidden: Bool, duration: TimeInterval, completion: ((Bool) -> Void)? = nil)`**\
263+
Fades the view in- or out, based on the provided hidden flag.
264+
265+
## GradientLoadingBarView
266+
267+
`GradientLoadingBarView` is the SwiftUI equivalent of `GradientActivityIndicatorView`.
268+
269+
### Basic Usage
270+
271+
```swift
272+
struct ContentView: some View {
273+
274+
var body: some View {
275+
GradientLoadingBarView()
276+
.frame(maxWidth: .infinity, maxHeight: 3)
277+
.cornerRadius(1.5)
278+
}
279+
}
280+
```
281+
282+
### Configuration
283+
284+
```swift
285+
GradientLoadingBarView(
286+
gradientColors: [.red, .white, .blue],
287+
progressDuration: 4.5,
288+
)
289+
```
290+
291+
#### Parameters
292+
293+
- **`gradientColors: [Color]`**\
294+
Defines the gradient colors.
295+
296+
- **`progressDuration: TimeInterval`**\
297+
Sets the animation speed.
298+
299+
### Visibility & Animation
300+
301+
Control the visibility using standard SwiftUI view modifiers such as:
302+
303+
- [`opacity(_:)`](<https://developer.apple.com/documentation/swiftui/view/opacity(_:)>)
304+
- [`hidden()`](<https://developer.apple.com/documentation/swiftui/view/hidden()>)
305+
306+
Example with fade animation:
307+
308+
```swift
309+
struct ContentView: some View {
310+
311+
@State
312+
private var isVisible = false
313+
314+
var body: some View {
315+
VStack {
316+
GradientLoadingBarView()
317+
.frame(maxWidth: .infinity, maxHeight: 3)
318+
.cornerRadius(1.5)
319+
.opacity(isVisible ? 1 : 0)
320+
.animation(.easeInOut, value: isVisible)
321+
322+
Button("Toggle visibility") {
323+
isVisible.toggle()
324+
}
325+
}
326+
}
327+
}
328+
```
329+
330+
## Author
331+
332+
Felix Mau
333+
me(@)felix.hamburg
334+
335+
## License
336+
337+
Gradient Loading Bar is released under the **MIT License**. See the `LICENSE` file for details.
338+
339+
[example]: Assets/screen.gif
340+
[ignoring-safe-area]: Assets/ignoring-safe-area.png
341+
[ignoring-safe-area-thumbnail]: Assets/ignoring-safe-area-thumbnail.png
342+
[ignoring-safe-area-animation]: Assets/ignoring-safe-area.mov
343+
[relative-to-safe-area]: Assets/relative-to-safe-area.png
344+
[relative-to-safe-area-thumbnail]: Assets/relative-to-safe-area-thumbnail.png
345+
[relative-to-safe-area-animation]: Assets/relative-to-safe-area.mov
346+
[notch-iphone-12-pro]: Assets/notch-iphone-12-pro.png
347+
[notch-iphone-12-pro-thumbnail]: Assets/notch-iphone-12-pro-thumbnail.png
348+
[notch-iphone-12-pro-animation]: Assets/notch-iphone-12-pro.mov
349+
[notch-iphone-13-pro-max]: Assets/notch-iphone-13-pro-max.png
350+
[notch-iphone-13-pro-max-thumbnail]: Assets/notch-iphone-13-pro-max-thumbnail.png
351+
[notch-iphone-13-pro-max-animation]: Assets/notch-iphone-13-pro-max.mov

0 commit comments

Comments
 (0)