Sapan Diwakar

Software developer

Follow me on Twitter Check out my code on GitHub View some of my designs on Dribbble Take a look at my Linked In profile

Custom parallax effect for iCarousel

iCarousel is a class designed to simplify the implementation of various types of carousel (paged, scrolling views) on iPhone, iPad and Mac OS. iCarousel implements a number of common effects such as cylindrical, flat and "CoverFlow" style carousels, as well as providing hooks to implement your own bespoke effects.

Lets try to create a simple parallax effect when changing pages in a horizontally set up iCarousel. We will implement carousel:itemTransformForOffset:baseTransform: in iCarousel delegate to supply carousel with our custom offset for different items in order to create the parallax effect (Don't forget to set the carousel type to iCarouselTypeCustom). In a linear sliding carousel, the outgoing view and the incoming view both move at the same speed. The parallax effect can be easily implemented by moving one of the views much slower (half the original speed in this case) than the other one.

Unfortunately, the delegate method doesn't tell us which view is being slid in and out. To move the incoming view at slower speed, I use a 'hacky' way of storing the carousel offset when the drag begins and then compare it with the current offset to estimate which direction the carousel is scrolled.

- (void)carouselWillBeginDragging:(iCarousel *)carousel {
    self.carouselScrollOffset = carousel.scrollOffset;
}

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform {
    CGFloat spacing = 1.0f;

    if (offset >= 1 || offset <= -1) {
        return CATransform3DTranslate(transform, offset * carousel.itemWidth * spacing, 0.0f, 0.0f);
    }
    if (carousel.scrollOffset > self.carouselScrollOffset && carousel.scrollOffset - self.carouselScrollOffset < 1) {
        // New item coming from right
        return CATransform3DTranslate(transform, offset / (offset > 0 ? 2.0 : 1) * carousel.itemWidth * spacing, 0.0f, 0.0f);
    } else {
        // New item coming from left
        return CATransform3DTranslate(transform, offset / (offset < 0 ? 2.0 : 1) * carousel.itemWidth * spacing, 0.0f, 0.0f);
    }
}

Thats all you need to get a cool parallax effect for your horizontal carousels.