You want to display a nice refresh UI control on top of your table views that allows your users to intuitively pull down the table view in order to update its contents. An example of a refresh control is shown in Figure 4-24.
Simply create a table view controller (as discussed in Recipe 4.9)
and set its refreshControl
property
to a new instance of UIRefreshControl
class, as shown here:
-
(
id
)
initWithStyle:
(
UITableViewStyle
)
style
{
self
=
[
super
initWithStyle
:
style
];
if
(
self
)
{
[
self
.
tableView
registerClass
:
[
UITableViewCell
class
]
forCellReuseIdentifier:
CellIdentifier
];
self
.
allTimes
=
[
NSMutableArray
arrayWithObject
:
[
NSDate
date
]];
/* Create the refresh control */
self
.
refreshControl
=
[[
UIRefreshControl
alloc
]
init
];
self
.
refreshControl
=
self
.
refreshControl
;
[
self
.
refreshControl
addTarget
:
self
action:
@selector
(
handleRefresh
:
)
forControlEvents:
UIControlEventValueChanged
];
}
return
self
;
}
Refresh controls are simple visual indicators that appear on top
of table views and tell the user that something is about to get updated.
For instance, prior to iOS 6, in order to refresh your mailbox in the
Mail app, you had to press a refresh button. In the new iOS, now you can
simply drag the list of your emails down, as if you wanted to see what’s
above there in the list that you haven’t read already. Once iOS detects
this gesture of yours, it will trigger a refresh. Isn’t that cool?
Twitter’s iPhone app started this whole thing when they added a refresh
control to their apps, so kudos to them for this. Apple has realized
that this is in fact a really nice and intuitive way of updating table
views and has since added a dedicated component to the SDK to implement
it. The class name for this component is UIRefreshControl
.
Create a new instance of this class simply by calling its init
method. Once you are done, add this
instance to your table view controller, as described in the Solution
section of this recipe.
Now you’ll want to know when the user has triggered a refresh
on your table view. To do this, simply call the addTarget:action:forControlEvents:
instance
method of your refresh control and pass the target object and a selector
on that object that takes care of the refresh for you. Pass UIControlEventValueChanged
to the forControlEvents
parameter of this
method.
Here—I want to demonstrate this to you. In this example, we will have a table view controller that displays the date and time formatted as strings. Once the user refreshes the list by pulling it down, we will add the current date and time again to the list and refresh our table view. This way, every time the user pulls the list down, it triggers a refresh that will allow us to add the current date and time to the list and refresh the table view to display the new date and time. So let’s start in the implementation file of our table view controller and define our refresh control and our data source:
#import "ViewController.h"
static
NSString
*
CellIdentifier
=
@"Cell"
;
@interface
ViewController
()
@property
(
nonatomic
,
strong
)
NSMutableArray
*
allTimes
;
@property
(
nonatomic
,
strong
)
UIRefreshControl
*
refreshControl
;
@end
@implementation
ViewController
The allTimes
property is a
simple mutable array that will contain all the instances of NSDate
in it as the user refreshes the table
view. We have already seen the initialization of our table view
controller in the Solution section of this recipe, so I won’t write it
again here. But as you saw there, we have hooked the UIControlEventValueChanged
event of our
refresh control to a method called handleRefresh:
. In this method, all we are
going to do is add the current date and time to our array of dates and
times and then refresh the table view:
-
(
void
)
handleRefresh:
(
id
)
paramSender
{
/* Put a bit of delay between when the refresh control is released
and when we actually do the refreshing to make the UI look a bit
smoother than just doing the update without the animation */
int64_t
delayInSeconds
=
1.0f
;
dispatch_time_t
popTime
=
dispatch_time
(
DISPATCH_TIME_NOW
,
delayInSeconds
*
NSEC_PER_SEC
);
dispatch_after
(
popTime
,
dispatch_get_main_queue
(),
^
(
void
){
/* Add the current date to the list of dates that we have
so that when the table view is refreshed, a new item will appear
on the screen so that the user will see the difference between
the before and the after of the refresh */
[
self
.
allTimes
addObject
:
[
NSDate
date
]];
[
self
.
refreshControl
endRefreshing
];
NSIndexPath
*
indexPathOfNewRow
=
[
NSIndexPath
indexPathForRow
:
self
.
allTimes
.
count
-
1
inSection
:
0
];
[
self
.
tableView
insertRowsAtIndexPaths:
@
[
indexPathOfNewRow
]
withRowAnimation:
UITableViewRowAnimationAutomatic
];
});
}
Last but not least, we will provide the date to our table view through the table view’s delegate and data source methods:
-
(
NSInteger
)
numberOfSectionsInTableView:
(
UITableView
*
)
tableView
{
return
1
;
}
-
(
NSInteger
)
tableView:
(
UITableView
*
)
tableView
numberOfRowsInSection:
(
NSInteger
)
section
{
return
self
.
allTimes
.
count
;
}
-
(
UITableViewCell
*
)
tableView:
(
UITableView
*
)
tableView
cellForRowAtIndexPath:
(
NSIndexPath
*
)
indexPath
{
UITableViewCell
*
cell
=
[
tableView
dequeueReusableCellWithIdentifier:
CellIdentifier
forIndexPath:
indexPath
];
cell
.
textLabel
.
text
=
[
NSString
stringWithFormat
:
@"%@"
,
self
.
allTimes
[
indexPath
.
row
]];
return
cell
;
}
Give this a go in either the simulator or the device. Once you open the app, at first you will see only one date/time added to the list. Keep dragging the table view down to get more items in the list (see Figure 4-24).
Get iOS 7 Programming Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.