Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/fxm90/GradientLoadingBar

⌛️A customizable animated gradient loading bar.
https://github.com/fxm90/GradientLoadingBar

cocoapods gradient ios loading-animations loading-bar loading-indicator swift

Last synced: 22 days ago
JSON representation

⌛️A customizable animated gradient loading bar.

Awesome Lists containing this project

README

        

GradientLoadingBar
====================

![Swift5.0](https://img.shields.io/badge/Swift-5.0-green.svg?style=flat) ![CI Status](https://img.shields.io/github/workflow/status/fxm90/GradientLoadingBar/Continuous%20Integration) ![Code Coverage](https://img.shields.io/codecov/c/github/fxm90/GradientLoadingBar.svg?style=flat) ![Version](https://img.shields.io/cocoapods/v/GradientLoadingBar.svg?style=flat) ![License](https://img.shields.io/cocoapods/l/GradientLoadingBar.svg?style=flat) ![Platform](https://img.shields.io/cocoapods/p/GradientLoadingBar.svg?style=flat)

A customizable animated gradient loading bar. Inspired by [iOS 7 Progress Bar from Codepen](https://codepen.io/marcobiedermann/pen/LExXWW).

### Example
![Example][example]

To run the example project, clone the repo, and open the workspace from the Example directory.

### Requirements
- Swift 5.5
- Xcode 13
- iOS 13.0+

**Note:** In case you need support for iOS versions lower than 13, you can fallback to version `2.X.X`.

### Integration
##### CocoaPods
[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate GradientLoadingBar into your Xcode project using CocoaPods, specify it in your `Podfile`:

```ruby
pod 'GradientLoadingBar', '~> 3.0'
```

##### Carthage
[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate GradientLoadingBar into your Xcode project using Carthage, specify it in your `Cartfile`:

```ogdl
github "fxm90/GradientLoadingBar" ~> 3.0
```
Run carthage update to build the framework and drag the built `GradientLoadingBar.framework` into your Xcode project.

##### Swift Package Manager
The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. It is in early development, but Gradient Loading Bar does support its use on supported platforms.

Once you have your Swift package set up, adding Gradient Loading Bar as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.

```swift
dependencies: [
.package(url: "https://github.com/fxm90/GradientLoadingBar", from: "3.0.0")
]
```

### How to use
This framework provides four classes:

- **GradientLoadingBar**: A controller, managing the visibility of the `GradientActivityIndicatorView` on the current key window.
- **NotchGradientLoadingBar**: A subclass of `GradientLoadingBar`, wrapping the `GradientActivityIndicatorView` around the notch of the iPhone.
- **GradientActivityIndicatorView**: A `UIView` containing the gradient with the animation. It can be added as a subview to another view either inside the interface builder or programmatically. Both ways are shown inside the example application.
- **GradientLoadingBarView**: A `View` for SwiftUI containing the gradient with the animation. The view can be added to any other SwiftUI view. The example application also contains sample code for this use case.

#### GradientLoadingBar
To get started, import the module `GradientLoadingBar` into your file and save an instance of `GradientLoadingBar()` on a property of your view-controller. To show the loading bar, simply call the `fadeIn(duration:completion)` method and after your async operations have finished call the `fadeOut(duration:completion)` method.

```swift
final class UserViewController: UIViewController {

private let gradientLoadingBar = GradientLoadingBar()

// ...

override func viewDidLoad() {
super.viewDidLoad()

gradientLoadingBar.fadeIn()

userService.loadUserData { [weak self] _ in
// ...
// Be sure to call this on the main thread!
self?.gradientLoadingBar.fadeOut()
}
}
}
```

##### Configuration
You can override the default configuration by calling the initializers with the optional parameters `height` and `isRelativeToSafeArea`:

```swift
let gradientLoadingBar = GradientLoadingBar(
height: 4.0,
isRelativeToSafeArea: true
)
```

###### – Parameter `height: CGFloat`
By setting this parameter you can set the height for the loading bar (defaults to `3.0`)

###### – Parameter `isRelativeToSafeArea: Bool`
With this parameter you can configure, whether the loading bar should be positioned relative to the safe area (defaults to `true`).

Example with `isRelativeToSafeArea` set to `true`.
[![Example][basic-example--thumbnail]][basic-example]

Example with `isRelativeToSafeArea` set to `false`.
[![Example][safe-area-example--thumbnail]][safe-area-example]

##### Note
There is a third option which will wrap the loading bar around the iPhone notch. See documentation of the class `NotchGradientLoadingBar` for further details.

##### Properties
###### – `gradientColors: [UIColor]`
This property adjusts the gradient colors shown on the loading bar.

###### – `progressAnimationDuration: TimeInterval`
This property adjusts the duration of the animation moving the gradient from left to right.

##### Methods
###### – `fadeIn(duration:completion)`
This method fades-in the loading bar. You can adjust the duration with corresponding parameter. Furthermore you can pass in a completion handler that gets called once the animation is finished.

###### – `fadeOut(duration:completion)`
This methods fades-out the loading bar. You can adjust the duration with corresponding parameter. Furthermore you can pass in a completion handler that gets called once the animation is finished.

##### Custom shared instance (Singleton)
If you need the loading bar on multiple / different parts of your app, you can use the given static `shared` variable:

```swift
GradientLoadingBar.shared.fadeIn()

// Do e.g. server calls etc.

GradientLoadingBar.shared.fadeOut()
```

If you wish to customize the shared instance, you can add the following code e.g. to your app delegate `didFinishLaunchingWithOptions` method and overwrite the `shared` variable:

```swift
GradientLoadingBar.shared = GradientLoadingBar(height: 5.0)
```

#### NotchGradientLoadingBar
This subclass of the `GradientLoadingBar` will wrap the loading bar around the notch of the iPhone.

For iPhones without a safe area, the behaviour stays the same as mentioned in the above documentation of the `GradientLoadingBar`.

```swift
let notchGradientLoadingBar = NotchGradientLoadingBar(
height: 3.0
)
```

[![Example][notch-example--thumbnail]][notch-example]

#### GradientActivityIndicatorView
In case you don't want to add the loading bar onto the key-window, this framework provides the `GradientActivityIndicatorView`, which is a direct subclass of `UIView`. You can add the view to another view either inside the interface builder or programmatically.

E.g. View added as a subview to a `UINavigationBar`.
[![Example][navigation-bar-example--thumbnail]][navigation-bar-example]

E.g. View added as a subview to a `UIButton`.
[![Example][advanced-example--thumbnail]][advanced-example]

##### Note
The progress-animation starts and stops according to the `isHidden` flag. Setting this flag to `false` will start the animation, setting this to `true` will stop the animation. Often you don't want to directly show / hide the view and instead smoothly fade it in or out. Therefore the view provides the methods `fadeIn(duration:completion)` and `fadeOut(duration:completion)`. Based on the gist [`UIView+AnimateAlpha.swift`](https://gist.github.com/fxm90/723b5def31b46035cd92a641e3b184f6), these methods adjust the `alpha` value of the view and update the `isHidden` flag accordingly.

##### Properties
###### – `gradientColors: [UIColor]`
This property adjusts the gradient colors shown on the loading bar.

###### – `progressAnimationDuration: TimeInterval`
This property adjusts the duration of the animation moving the gradient from left to right.

*To see all these screenshots in a real app, please have a look at the **example application**. For further customization you can also subclass `GradientLoadingBar` and overwrite the method `setupConstraints()`.*

#### GradientLoadingBarView
This is the SwiftUI variant for the `GradientActivityIndicatorView`. The view can be configured via the two parameters `gradientColors: [Color]` and `progressDuration: TimeInterval` passed to the initializer.

##### – `gradientColors: [Color]` :
This parameter adjusts the gradient colors shown on the loading bar.

##### – `progressDuration: TimeInterval` :
This parameter adjusts the duration of the animation moving the gradient from left to right.

The visibility of the view can be updated with the view modifier [`opacity()`](https://developer.apple.com/documentation/swiftui/view/opacity(_:)) or [`hidden()`](https://developer.apple.com/documentation/swiftui/view/hidden()).

To animate the visibility changes you need to create a property with the `@State` property wrapper, and update the value from a [`withAnimation`](https://developer.apple.com/documentation/swiftui/withanimation(_:_:)) block, e.g.

```swift
struct ExampleView: some View {

@State
private var isVisible = false

var body: some View {
VStack {
GradientLoadingBarView()
.frame(maxWidth: .infinity, maxHeight: 3)
.cornerRadius(1.5)
.opacity(isVisible ? 1 : 0)

Button("Toggle visibility") {
withAnimation(.easeInOut) {
isVisible.toggle()
}
}
}
}
}
```

### Troubleshooting
#### Interface Builder Support
Unfortunately the Interface Builder support is currently broken for Cocoapods frameworks. If you need Interface Builder support, add the following code to your Podfile and run `pod install` again. Afterwards you should be able to use the `GradientLoadingBar` inside the Interface Builder :)

```
post_install do |installer|
installer.pods_project.build_configurations.each do |config|
next unless config.name == 'Debug'

config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = [
'$(FRAMEWORK_SEARCH_PATHS)'
]
end
end
```
Source: [Cocoapods – Issue 7606](https://github.com/CocoaPods/CocoaPods/issues/7606#issuecomment-484294739)

### Author
Felix Mau (me(@)felix.hamburg)

### License

GradientLoadingBar is available under the MIT license. See the LICENSE file for more info.

[example]: Assets/screen.gif

[basic-example]: Assets/basic-example.png
[basic-example--thumbnail]: Assets/basic-example--thumbnail.png

[safe-area-example]: Assets/safe-area-example.png
[safe-area-example--thumbnail]: Assets/safe-area-example--thumbnail.png

[notch-example]: Assets/notch-example.png
[notch-example--thumbnail]: Assets/notch-example--thumbnail.png

[navigation-bar-example]: Assets/navigation-bar-example.png
[navigation-bar-example--thumbnail]: Assets/navigation-bar-example--thumbnail.png

[advanced-example]: Assets/advanced-example.png
[advanced-example--thumbnail]: Assets/advanced-example--thumbnail.png