Latest 0.7.0
License MIT
Platforms ios 8.0, requires ARC


A view controller category which presents UIViews for loading, error and empty states.


  • iOS 8.0+
  • Xcode 7.0+
  • Objective-C

It’s also compatible with Swift.



StateViewController is available through CocoaPods. To install
it, simply add the following line to your Podfile:

pod 'StateViewController'

Then just run pod install.


Just drag and drop all files from folder Source in the StateViewController into your project and select Copy items if needed.


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.


First make sure that you have imported category.


#import <StateViewController/UIViewController+StateViewController.h>


#import "UIViewController+StateViewController.h"

Then make sure that your UIViewController or UITableViewController or UICollectionViewController adopts protocol StateViewController.

@interface ViewController () <StateViewController>
 // Code

Then, 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:@""]];
    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];


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.


Pavol Kmet


This pod takes inspiration from Swift version of StatefulViewController by Alexander Schuch with some minor differences.


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

Latest podspec

    "name": "StateViewController",
    "version": "0.7.0",
    "summary": "Small category which handle loading, empty and error states of view controller.",
    "description": "A view controller category which presents `UIView` for loading, error and empty states.",
    "homepage": "",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    "authors": {
        "Pavol Kmet": "[email protected]"
    "social_media_url": "",
    "platforms": {
        "ios": "8.0"
    "source": {
        "git": "",
        "tag": "0.7.0"
    "source_files": "Sources/*.{h,m}",
    "ios": {
        "frameworks": "UIKit"
    "requires_arc": true

Pin It on Pinterest

Share This