Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aschuch/StatefulViewController
Placeholder views based on content, loading, error or empty states
https://github.com/aschuch/StatefulViewController
empty error loading placeholder state state-management swift uiviewcontroller
Last synced: 3 months ago
JSON representation
Placeholder views based on content, loading, error or empty states
- Host: GitHub
- URL: https://github.com/aschuch/StatefulViewController
- Owner: aschuch
- License: mit
- Created: 2014-09-02T18:32:32.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2020-11-12T08:46:46.000Z (almost 4 years ago)
- Last Synced: 2024-04-14T14:51:27.023Z (7 months ago)
- Topics: empty, error, loading, placeholder, state, state-management, swift, uiviewcontroller
- Language: Swift
- Homepage:
- Size: 498 KB
- Stars: 2,136
- Watchers: 34
- Forks: 148
- Open Issues: 23
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ios - StatefulViewController - Placeholder views based on content, loading, error or empty states. (UI / TextField & TextView)
- awesome-swift - StatefulViewController - Placeholder views based on content, loading, error or empty states. (Libs / UI)
- awesome-swift - StatefulViewController - Placeholder views based on content, loading, error or empty states. (Libs / UI)
- awesome-ios-star - StatefulViewController - Placeholder views based on content, loading, error or empty states. (UI / TextField & TextView)
- fucking-awesome-swift - StatefulViewController - Placeholder views based on content, loading, error or empty states. (Libs / UI)
- awesome-swift - StatefulViewController - Placeholder views based on content, loading, error or empty states ` 📝 4 years ago ` (UI [🔝](#readme))
README
# StatefulViewController
[![Build Status](https://travis-ci.org/aschuch/StatefulViewController.svg)](https://travis-ci.org/aschuch/StatefulViewController)
![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)
![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg)
![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20tvOS-lightgrey.svg)A protocol to enable `UIViewController`s or `UIView`s to present placeholder views based on content, loading, error or empty states.
![StatefulViewController Example](Resources/example.gif)
## Overview
In a networked application a view controller or custom view typically has the following states that need to be communicated to the user:
* **Loading**: The content is currently loaded over the network.
* **Content**: The content is available and presented to the user.
* **Empty**: There is currently no content available to display.
* **Error**: An error occurred whilst downloading content.As trivial as this flow may sound, there are a lot of cases that result in a rather large decision tree.
![Decision Tree](Resources/decision_tree.png)
`StatefulViewController` is a concrete implementation of this particular decision tree. (If you want to create your own modified version, you might be interested in the [state machine](#viewstatemachine) that is used to show and hide views.)
## Version Compatibility
Current Swift compatibility breakdown:
| Swift Version | Framework Version |
| ------------- | ----------------- |
| 3.0 | 3.x |
| 2.3 | 2.x |
| 2.2 | 1.x |[all releases]: https://github.com/aschuch/StatefulViewController/releases
## Usage
> This guide describes the use of the `StatefulViewController` protocol on `UIViewController`. However, you can also adopt the `StatefulViewController` protocol on any `UIViewController` subclass, such as `UITableViewController` or `UICollectionViewController`, as well as your custom `UIView` subclasses.
First, make sure your view controller adopts to the `StatefulViewController` protocol.
```swift
class MyViewController: UIViewController, StatefulViewController {
// ...
}
```Then, configure the `loadingView`, `emptyView` and `errorView` properties (provided by the `StatefulViewController` protocol) in `viewDidLoad`.
```swift
override func viewDidLoad() {
super.viewDidLoad()// Setup placeholder views
loadingView = // UIView
emptyView = // UIView
errorView = // UIView
}
```In addition, call the `setupInitialViewState()` method in `viewWillAppear:` in order to setup the initial state of the controller.
```swift
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)setupInitialViewState()
}
```After that, simply tell the view controller whenever content is loading and `StatefulViewController` will take care of showing and hiding the correct loading, error and empty view for you.
```swift
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)loadDeliciousWines()
}func loadDeliciousWines() {
startLoading()let url = NSURL(string: "http://example.com/api")
let session = NSURLSession.sharedSession()
session.dataTaskWithURL(url) { (let data, let response, let error) in
endLoading(error: error)
}.resume()
}
```### Life cycle
StatefulViewController calls the `hasContent` method to check if there is any content to display. If you do not override this method in your own class, `StatefulViewController` will always assume that there is content to display.
```swift
func hasContent() -> Bool {
return datasourceArray.count > 0
}
```Optionally, you might also be interested to respond to an error even if content is already shown. `StatefulViewController` will not show its `errorView` in this case, because there is already content that can be shown.
To e.g. show a custom alert or other unobtrusive error message, use `handleErrorWhenContentAvailable:` to manually present the error to the user.
```swift
func handleErrorWhenContentAvailable(error: ErrorType) {
let alertController = UIAlertController(title: "Ooops", message: "Something went wrong.", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(alertController, animated: true, completion: nil)
}
```### Custom Placeholder View insets
Per default, StatefulViewController presents all configured placeholder views fullscreen (i.e. with 0 insets from top, bottom, left & right from the superview). In case a placeholder view should have custom insets the configured placeholderview may conform to the `StatefulPlaceholderView` protocol and override the `placeholderViewInsets` method to return custom edge insets.
```swift
class MyPlaceholderView: UIView, StatefulPlaceholderView {
func placeholderViewInsets() -> UIEdgeInsets {
return UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
}
}
```### View State Machine
> Note: The following section is only intended for those, who want to create a stateful controller that differs from the flow described above.
You can also use the underlying view state machine to create a similar implementation for your custom flow of showing/hiding views.
```swift
let stateMachine = ViewStateMachine(view: view)// Add states
stateMachine["loading"] = loadingView
stateMachine["other"] = otherView// Transition to state
stateMachine.transitionToState(.View("loading"), animated: true) {
println("finished switching to loading view")
}// Hide all views
stateMachine.transitionToState(.None, animated: true) {
println("all views hidden now")
}
```## Installation
#### Carthage
Add the following line to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile).
```
github "aschuch/StatefulViewController" ~> 3.0
```Then run `carthage update`.
#### CocoaPods
Add the following line to your Podfile.
```
pod "StatefulViewController", "~> 3.0"
```Then run `pod install` with CocoaPods 0.36 or newer.
#### Manually
Just drag and drop the two `.swift` files in the `StatefulViewController` folder into your project.
## Tests
Open the Xcode project and press `⌘-U` to run the tests.
Alternatively, all tests can be run from the terminal using [xctool](https://github.com/facebook/xctool).
```bash
xctool -scheme StatefulViewControllerTests -sdk iphonesimulator test
```## Todo
* Default loading, error, empty views
* Protocol on views that notifies them of removal and add
* Views can provide delays in order to tell the state machine to show/remove them only after a specific delay (e.g. for hide and show animations)## Contributing
* Create something awesome, make the code better, add some functionality,
whatever (this is the hardest part).
* [Fork it](http://help.github.com/forking/)
* Create new branch to make your changes
* Commit all your changes to your branch
* Submit a [pull request](http://help.github.com/pull-requests/)## Contact
Feel free to get in touch.
* Website:
* Twitter: [@schuchalexander](http://twitter.com/schuchalexander)