Add Pull to Refresh to a table view in iOS 6

iOS 6 Introduces the UIRefreshControl to use with table views. When pulled,  a little wheel starts spinning at the top, until the refresh has completed.  At that time, the wheel disappears, and the view bounces back into place. In this tutorial we will add a refresh control to a table view. When the controll is pulled the sorting order of the rows will be inversed.

Update: Nov 26, 2014. The rewritten version in Swift for iOS 8 and Xcode 6 is available here.

Open Xcode and create a new Empty Application. For product name, use PullToRefreshDemo and then fill out the Organization Name, Company Identifier and Class Prefix fields with your customary values. Make sure only iPhone is selected in Devices, and that the Use Storyboards is deselected and Use Automatic Reference Counting checkbox is selected.

Add a New File -> Objective -C class. Name the class LetterViewController and make it a subclass of UITableViewController. Don't select the "With XIB for user interface" checkbox as we will do everything in code this time. When you look inside LetterViewController.m all required methods are already implemented. Pretty convenient, huh?

Go to AppDelegate.m and import our view controller header file.

#import "LetterViewController.h"

Add the following lines in the application:didFinishLaunchingWithOptions method

// Override point for customization after application launch. 
LetterViewController *letterVC = [[LetterViewController alloc] initWithStyle:UITableViewStylePlain];
self.window.rootViewController = letterVC;

A plain style table view controller is initialised and assigned to the rootviewController property of the window. If you Build and Run the project now, you should see an empty tableview.

To display some data we will create an array of letters. Go to LetterViewController.m and create a property in the interface section

@interface LetterViewController ()

@property (nonatomic, strong) NSMutableArray *letterData;


In ViewDidLoad add some letters to the array

self.letterData = [@[@"A",@"B",@"C",@"D",@"E"] mutableCopy];

Change the numberOfSectionsInTableView method to

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;

We use only one section in the table view.Change the tableView:numberOfRowsInSection method to

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [self.letterData count];

This method simply returns the number of letters in the letterData array. Change the tableView:cellForRowAtIndexPath method to


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; }

cell.textLabel.text = self.letterData[indexPath.row];

return cell;

Every time this method is called the current row will be filled with the letter from our letterDate array. Build and run to see the rows displayed on the table view.

Now that some rows are filled let's get going with the refresh control. If we pull to refresh We want the rows to sort in descending/ascending order. First we need a Boolean to switch the sort order. Add the following property in the interface section.

@property (nonatomic) BOOL isAscending;

In viewDidLoad, set the start value of this boolean to YES

self.isAscending = YES

Add the following lines to the end of viewDidLoad to initialise the refresh control.

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(sortArray) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;

Every time the refresh controll is pulled the UICOntrolEventValueChanged event is triggered, which will call the sortArray method. Let's implement this method.

- (void)sortArray 
self.isAscending = !self.isAscending;
NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: @"self" ascending:self.isAscending];
NSArray *sortedArray = [self.letterData sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];

NSUInteger index = 0;
for (NSString *s in sortedArray) {
self.letterData[index] = s;
index++; }

[self.tableView reloadData];
[self.refreshControl endRefreshing];

A lot is happening here. First the value of isAscending is inversed, which will switch the sorting order. This sort order is loaded in the sort descriptor. A sorted array is created, containing all the sorted values. With the help of fast enumeration the sorted values will be assigned to our letterData array. Finally we reload the tableView and will stop the refreshControl from refreshing. Build and Run, Pull-refresh a few times and you see the switching of the sorting order of the rows in the table view.

You can download the source code of the PullToRefreshDemo at the ioscreator repository on github.