StateViewController
A view controller category which presents UIViews for loading, error and empty states.
Requirements
- iOS 8.0+
- Xcode 7.0+
- Objective-C
It's also compatible with Swift.
Installation
CocoaPods
StateViewController is available through CocoaPods. To install
it, simply add the following line to your Podfile:
pod 'StateViewController'Then just run pod install.
Manually
Just drag and drop all files from folder Source in the StateViewController into your project and select Copy items if needed.
Overview
State View Controller allows you to easily manager four most common states:
- Loading state: View controller loads data from network. Loading view is presented.
- Error state: An error occurred while loading data from network. Error view is presented.
- Empty state: Data has been retrieved, but content is not available. Empty view is presented.
- Content state: Content is available and it's presented.
Usage
First make sure that you have imported category.
CocoaPods
#import <StateViewController/UIViewController+StateViewController.h>Manually
#import "UIViewController+StateViewController.h"Then make sure that your UIViewController or UITableViewController or UICollectionViewController adopts protocol StateViewController.
@interface ViewController () <StateViewController>
// Code
@endThen, configure the loadingView, emptyView and errorView properties in viewDidLoad.
- (void)viewDidLoad
{
[super viewDidLoad];
self.loadingView = // Custom loading view type of UIView
self.errorView = // Custom error view type of UIView
self.emptyView = // Custom empty view type of UIView
}After that in viewWillAppear: method you must call setupInitialState method which setup as method name says initial state of view controller.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setupInitialState];
}After that, simply tell the view controller whenever content is loading and StateViewController will take care of showing and hiding the correct loading, error and empty view for you.
- (void)viewDidLoad
{
[super viewDidLoad];
// After setting loading, error, empty views
[self fetchData];
}
- (void)fetchData
{
[self startLoadingAnimated:YES completion:nil];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
//
[self endLoadingAnimated:YES error:error completion:nil];
}];
[task resume];
}Life cycle
StateViewController calls the hasContent method to check if there is any content to display. If you do not implement this method in your own UIViewController, StateViewController will always assume that there is no content to display.
But if your view controller is kind of class UITableViewController or UICollectionViewController, StateViewController in default implementation check if numberOfSections > 0.
- (BOOL)hasContent
{
return self.people.count > 0;
}Also you might also be interested to respond to an error even if content is already shown. StateViewController will not show an errorView in this case, because there is already content that can be shown.
To e.g. show a custom alert or other error message, use handleErrorWhenContentsAvailable: to manually present the error to the user.
- (void)handleErrorWhenContentsAvailable:(NSError *)error
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error" message:error.localizedDescription preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}Configuration
If your view (loading, error, empty) should have insets you can implement in you view controller method with name insetForStateView: which is called every time before the view is presented.
- (UIEdgeInsets)insetForStateView:(UIView *)stateView
{
return UIEdgeInsetsZero;
}You can also customize your views (empty view, error view) before each view is added to view hierarchy.
Empty view
- (UIView *)configureEmptyView:(UIView *)view
{
return view;
}Default implementation does nothing.
Error view
- (UIView *)configureErrorView:(UIView *)view withError:(NSError *)error
{
return view;
}Default implementation does nothing.
Author
Pavol Kmet
- Email: [email protected]
- Twitter: @PavolKmet
Inspiration
This pod takes inspiration from Swift version of StatefulViewController by Alexander Schuch with some minor differences.
License
StateViewController is available under the MIT license. See the LICENSE file for more info.
