Thumbnail2

Back to Blog

Building a paged carousel

Posted on 11 Feb 2014 Written by Alison Clarke

Using a page control to scroll a carousel is a common UI idiom, and it’s really easy to add to your iOS app with ShinobiEssentials!

We’ve created a PagedCarouselHelper class available on GitHub, which you can just download and plug in to your own app. This tutorial will take you through how to use the helper, to create a whole variety of paged carousels:

Examples

Before you start, you’ll need a copy of ShinobiEssentials – download a free trial if you don’t already have one.

Setting up your project

In our example, we’ll use a Single View Application in Xcode, set up for iPad. You’ll need to add the following libraries to your project:

  • QuartzCore.framework
  • Security.framework (only needed by trial users)
  • ShinobiEssentials.framework (if you’ve used the installer, this should be available under “Developer Frameworks”; otherwise you’ll need to drag-drop in ShinobiEssentials.framework from wherever you extracted the files.

If you’re using the trial version you’ll need to add your license key. Open up AppDelegate.m, import <ShinobiEssentials/SEssentials.h>, and set the license key inside application:didFinishLaunchingWithOptions: as follows:

#import <ShinobiEssentials/SEssentials.h>
 
@implementation AppDelegate
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [SEssentials setLicenseKey:@"your license key"];
    …
}

Adding the UI components

To use PagedCarouselHelper, you’ll first need an SEssentialsCarousel and a UIPageControl. We’ll create these using the main storyboard.

To add the carousel, add a UIView to your storyboard, then open its Identity Inspector and change the class to be SEssentialsLinear3D. (We’ve chosen to use a linear 3D carousel in our example, but you can use any carousel implementation – there’s a full list of built-in types in the SEssentialsCarousel overview.)

Next, add a Page Control to the storyboard. We changed the colors on ours to make it stand out better on a light background: under the Attributes inspector, set the Tint Color to “Dark Text Color” and the Current Page to “Dark Gray Color”.

Play around with the layout and constraints until you’re happy. Our storyboard ended up looking like this:

Interfacebuilder

Now, open up the Assistant editor and in turn right-click and drag the carousel and page control to your view controller implementation, to create IBOutlet properties called carousel and pageControl respectively. You’ll also need to import <ShinobiEssentials/ShinobiEssentials.h>. So the top of your ViewController.m file should look something like this:

#import "ViewController.h"
#import <ShinobiEssentials/ShinobiEssentials.h>

@interface ViewController ()
@property (weak, nonatomic) IBOutlet SEssentialsCarouselLinear3D *carousel;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;

@end

Adding the PagedCarouselHelper

It’s time to get hold of the PagedCarouselHelper class from our GitHub project. Download the following files and add them to your project:

Import PagedCarouselHelper.h in your view controller implementation, and add a PagedCarouselHelper property:

@implementation ViewController {
    PagedCarouselHelper *_helper;
}

Now add the following line to viewDidLoad, to instantiate your helper:

_helper = [[PagedCarouselHelper alloc] initWithCarousel:self.carousel pageControl:self.pageControl];

Adding your views

You’ll probably want to add some interesting views to your carousel, but for now we’re just going to add some colored labels. Add the following code to viewDidLoad:

int numberOfItems = 10;
    
// Set up some views and add them to the carousel
for (int i=0; i<numberOfItems; i++) {
    // Create a UILabel with a number and coloured background
    UILabel *view = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
    view.text = [NSString stringWithFormat:@"%i", i+1];
    view.textColor = [UIColor whiteColor];
    view.textAlignment = NSTextAlignmentCenter;
    view.font = [UIFont fontWithName:@"Arial" size:100];
    view.backgroundColor = [UIColor colorWithHue:((float)i)/numberOfItems saturation:1.0 brightness:0.5 alpha:1.0];
        
    // Add the UILabel to the PagedCarouselHelper
    [_helper addView:view];
}

The first part of this loop creates a view, setting its background color so that our views span the spectrum. The last line is the important one: it adds the view to the paged carousel helper.

If you run the app now, you should see a paged carousel! Or perhaps not…if your app won’t run, it might be that the linker doesn’t realize that we need the SEssentialsCarouselLinear3D class, because our carousel was created through IB and we’re not using any of its methods directly in our code. You can fix this either by adding the –ObjC flag to the “Other Linker Flags” in the project build settings, or by adding a call to [SEssentialsCarouselLinear3D class] somewhere in your view controller.

Try again, and hopefully your app will appear! The page control displays a page for each view in the carousel. Scrolling the carousel changes the page on the page control, and tapping the page control scrolls the carousel.

Linear3d 1Itemperpage

Multiple views per page

Well that’s all very nice, but what if you want to display more than one view in each page? No problem: just set the itemsPerPage property on your helper:

_helper.itemsPerPage = 3;

It’s more efficient to add this line before you add your views, but you can change it later on if you like. Run your carousel now and you should see something like this:

Linear3d 3Itemsperpage

Each page now displays 3 carousel views.

Tweaks and tips

You may have noticed that when you scroll the carousel, the page control takes a while to update. That’s because it doesn’t change until the carousel has finished scrolling, and the default animation curve takes a while to finish. We can make the scroll finish more quickly by adjusting the animation curve applied to the carousel:

// Tweak carousel animation to work nicely with page control
self.carousel.momentumAnimationCurve = [SEssentialsAnimationCurve curveForCurveType:SEssentialsAnimationCurveTypeLinear];

When the carousel slows down, it will now use a linear animation curve, which comes to a halt more quickly than the default animation. You might want to play with the various other animation curves provided by ShinobiEssentials, or even to write your own animation.

There are various other properties you can configure on the helper:

  • itemPadding: adjusts the spacing between the views on a page
  • orientation: whether to line up the items within a page horizontally or vertically
  • animationDuration: how long the animated scroll takes when the user changes the page via the page control

When it comes to adding your own views to the helper, please note that the PagedCarouselHelper is designed to work with views that are all the same size – you might see some odd behavior otherwise.

More examples

As I mentioned earlier, you can use any implementation of SEssentialsCarousel with the helper. If you want to have multiple views per page, then the linear carousels will probably look best. Here are a few examples:

  • 2D linear carousel, with both carousel and helper orientations set to vertical, and 3 items per page:

Linear2d

  • Cylindrical carousel, with 1 item per page:

Cylindrical

  • Cover flow, with 3 items per page, and the carousel orientation vertical but the helper orientation horizontal:

Coverflow

How the paged carousel helper works

Here’s a summary of how PagedCarouselHelper works:

  • To make the page control change when the user has scrolled the carousel, it implements the SEssentialsCarouselDelegate method carousel:didFinishScrollingAtOffset: and updates the page control’s current page.
  • To make the carousel scroll when the user taps the page control, the helper adds a target action to the page control, triggered by the UIControlEventValueChanged event, which calls setContentOffset:animated:withDuration: on the carousel.
  • To include multiple views on the same page, the helper creates wrapper views to which the given views are added; it is these wrapper views that are then added to the carousel.

If you want to know more, take a look at PagedCarouselHelper.m – it’s reasonably well-commented so hopefully you’ll be able to work out what’s going on, but if you get stuck, let us know. And if you think you can improve on it, please fork the project and show us what you can do!

Summing it up

So there we have it – a helper class that makes it really easy to build your own paged carousels. If you got stuck, have a look at the completed project on GitHub. We hope you’ll find it useful – let us know what you use it for!

Back to Blog