Starting from now I will spend a few post talking about an app that I made shortly before starting at Brilliant Service, during my job search period. I think there are some implementations that might be interesting for other developers out there.
Take a look at iNippon in the iTunes Preview page here:
English JapaneseIn this post I'll share my experiences of implementing the UIPageViewController that is used in the new template Page-Based Application found in Xcode. For those of you who are not familiar with this, take a look at the iBooks app. The API for creating this beautiful and natural turning of pages is now made available using the UIPageViewController.
What the implementation in iNippon looks like can be seen in this screenshot.
|
iNippon, Today's view |
Similar to UITableViewController, UIPageViewController takes a delegate and a datasource. Simply put, the datasource provide UIViewControllers for the UIPageViewController to display. The template in Xcode provides a fully functional implementation and it shouldn't be any problem to get ones head around how it works.
ProblemThe template provided by Apple in Xcode creates new UIViewControllers on the fly when you start to turn the page. I started with this approach and it worked fine in the simulator and on the older generation iPod Touch and iPhone 3GS but on the iPhone 4 it was really slow and jerky. At first I thought this was weird but found the answer when removing the loading of the background image made it really fast and smooth. One might think that the iPhone 4 should be faster at loading images than the 3GS but in this case I used separate images sizes using the @2x suffix so the 3GS only loads an image that is 320x367 while the iPhone 4 uses an image that is 640x734 pixels, four times as much data as the lower resolution. Even though the iPhone 4 is faster it's not four times faster at this task, it seems.
SolutionSo, have should we handle this? Some users might never turn the page while some users might use this functionality to flick through pages in a fast pace. Ten background images with different motives are used and loading them all into memory seems like a waste of valuable resources, especially considering most of them might not even be displayed. Remember memory is a valuable resource in mobile devices and by keeping our memory footprint low we keep other apps from being deallocated as well as improving our own loading time which will improve the overall user experience.
The solution came to be a compromise between fast page turning and memory usage. What I do is, in the datasource I keep an NSArray with 3 UIViewControllers, loaded and ready to be displayed. The one in the middle position is the one currently on screen, the others are the previous and the next page. If you turn a page the UIViewController at the next position is provided to the UIPageViewController and once the UIPageViewController has finished it's animations the next UIViewController is loaded and inserted into the array so that the array always contains three UIViewControllers. Of course, I have to keep the user from turning page again until the new UIViewController has loaded completely but this is easy done by deactivating the UIGestureRecognizers during this time. If the user takes the time to look through the content of the page, the new UIViewController will be loaded and ready well in time before the user turns page again. And as always, the edge case has to be handle separately when the user is on page zero and there are no more pages in back direction.
Utilize the UIPageViewController and create beautiful page-based applications you too. They provide a great user experience and make it fun to flick through pages.