iCarousel
Overview
iCarousel is a class designed to simplify the implementation of various types of carousel on iPhone and iPad. iCarousel implements a number of common effects such as cylindrical, flat and "CoverFlow" style carousels.
iCarousel is a class designed to simplify the implementation of various types of carousel (paged, scrolling views) on iPhone, iPad.
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.
Unlike many other "CoverFlow" libraries, iCarousel can work with any kind of view, not just images, so it is ideal for presenting paged data in a fluid and impressive way in your app. It also makes it extremely easy to swap between different carousel effects with minimal code changes.
Supported build target - iOS 5.0 / Mac OS 10.7 (Xcode 4.2, Apple LLVM compiler 3.0)
Earliest supported deployment target - iOS 4.3 / Mac OS 10.7 (Xcode 4.2)
Earliest compatible deployment target - iOS 3.2 / Mac OS 10.6
NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this iOS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.
As of version 1.6.1, iCarousel automatically works with both ARC and non-ARC projects through conditional compilation. There is no need to exclude iCarousel files from the ARC validation process, or to convert iCarousel using the ARC conversion tool.
To use the iCarousel class in an app, just drag the iCarousel class files (demo files and assets are not needed) into your project and add the QuartzCore framework.
iCarousel supports the following built-in display types:
iCarouselTypeLinear
iCarouselTypeRotary
iCarouselTypeInvertedRotary
iCarouselTypeCylinder
iCarouselTypeInvertedCylinder
iCarouselTypeWheel
iCarouselTypeInvertedWheel
iCarouselTypeCoverFlow
iCarouselTypeCoverflow2
iCarouselTypeTimeMachine
iCarouselTypeInvertedTimeMachine
You can also implement your own bespoke carousel styles using iCarouselTypeCustom and the carousel:itemTransformForOffset:baseTransform: delegate method.
NOTE: The difference between iCarouselTypeCoverFlow and iCarouselTypeCoverFlow2 types is quite subtle, however the logic for iCarouselTypeCoverFlow2 is substantially more complex. If you flick the carousel they are basically identical, but if you drag the carousel slowly with your finger the difference should be apparent. iCarouselTypeCoverFlow2 is designed to simulate the standard Apple CoverFlow effect as closely as possible and may change subtly in future in the interests of that goal.
The iCarousel has the following properties (note: for Mac OS, substitute NSView for UIView when using properties):
@property (nonatomic, assign) IBOutlet id<iCarouselDataSource> dataSource;
An object that supports the iCarouselDataSource protocol and can provide views to populate the carousel.
@property (nonatomic, assign) IBOutlet id<iCarouselDelegate> delegate;
An object that supports the iCarouselDelegate protocol and can respond to carousel events and layout requests.
@property (nonatomic, assign) iCarouselType type;
Used to switch the carousel display type (see above for details).
@property (nonatomic, assign) CGFloat perspective;
Used to tweak the perspective foreshortening effect for the various 3D carousel views. Should be a negative value, less than 0 and greater than -0.01. Values outside of this range will yield very strange results. The default is -1/500, or -0.005;
@property (nonatomic, assign) CGSize contentOffset;
This property is used to adjust the offset of the carousel item views relative to the center of the carousel. It defaults to CGSizeZero, meaning that the carousel items are centered. Changing this value moves the carousel items without changing their perspective, i.e. the vanishing point moves with the carousel items, so if you move the carousel items down, it does not appear as if you are looking down on the carousel.
@property (nonatomic, assign) CGSize viewpointOffset;
This property is used to adjust the user viewpoint relative to the carousel items. It has the opposite effect to adjusting the contentOffset, i.e. if you move the viewpoint up then the carousel appears to move down. Unlike the contentOffset, moving the viewpoint also changes the perspective vanishing point relative to the carousel items, so if you move the viewpoint up, it will appear as if you are looking down on the carousel.
@property (nonatomic, assign) CGFloat decelerationRate;
The rate at which the carousel decelerates when flicked. Higher values mean slower deceleration. The default value is 0.95. Values should be in the range 0.0 (carousel stops immediately when released) to 1.0 (carousel continues indefinitely without slowing down, unless it reaches the end).
@property (nonatomic, assign) BOOL bounces;
Sets whether the carousel should bounce past the end and return, or stop dead. Note that this has no effect on carousel types that are designed to wrap, or where the carouselShouldWrap delegate method returns YES.
@property (nonatomic, assign) CGFloat bounceDistance;
The maximum distance that a non-wrapped carousel will bounce when it overshoots the end. This is measured in multiples of the itemWidth, so a value of 1.0 would means the carousel will bounce by one whole item width, a value of 0.5 would be half an item's width, and so on. The default value is 1.0;
@property (nonatomic, assign) BOOL scrollEnabled;
Enables and disables user scrolling of the carousel. The carousel can still be scrolled programmatically if this property is set to NO.
@property (nonatomic, readonly) NSInteger numberOfItems;
The number of items currently displayed in the carousel (read only). To set this, implement the numberOfItemsInCarousel: dataSource method.
@property (nonatomic, readonly) NSInteger numberOfPlaceholders;
The number of placeholder views to display in the carousel (read only). To set this, implement the numberOfPlaceholdersInCarousel: dataSource method.
@property (nonatomic, readonly) NSInteger numberOfVisibleItems;
The maximum number of carousel item views to be displayed concurrently on screen (read only). To set this, implement the numberOfVisibleItemsInCarousel: dataSource method. If the dataSource method is not implemented, this will be equal to the numberOfItems + numberOfPlaceholders;
@property (nonatomic, retain, readonly) NSArray *indexesForVisibleItems;
An array containing the indexes of all item views currently visible in the carousel, including placeholder views. The array contains NSNumber objects whose integer values match the indexes of the views. The indexes for item views start at zero and match the indexes passed to the dataSource to load the view, however the indexes for any visible placeholder views will either be negative (less than zero) or greater than or equal to numberOfItems. Indexes for placeholder views in this array do not equate to the placeholder view index used with the dataSource.
@property (nonatomic, retain, readonly) NSArray *visibleItemViews;
An array of all the item views currently displayed in the carousel (read only). This includes any visible placeholder views. The indexes of views in this array do not match the item indexes, however the order of these views matches the order of the visibleItemIndexes array property, i.e. you can get the item index of a given view in this array by retrieving the equivalent object from the visibleItemIndexes array (or, you can just use the indexOfItemView: method, which is much easier).
@property (nonatomic, retain, readonly) UIView *contentView;
The view containing the carousel item views. You can add subviews to this view if you want to intersperse them with the carousel items. If you want a view to appear in front or behind all of the carousel items, you should add it directly to the iCarousel view itself instead. Note that the order of views inside the contentView is subject to frequent and undocumented change while the app is running. Any views added to the contentView should have their userInteractionEnabled property set to NO to prevent conflicts with iCarousel's touch event handling.
@property (nonatomic, readonly) CGFloat scrollOffset;
This is the current offset in pixels of the carousel. This value, divided by the itemWidth is the currentItemIndex value. You can use this value to position other screen elements while the carousel is in motion.
@property (nonatomic, readonly) CGFloat offsetMultiplier;
This is the offset multiplier used when the user drags the carousel with their finger. It does not affect programmatic scrolling or deceleration speed. This defaults to 1.0 for most carousel types, but defaults to 2.0 for the CoverFlow-style carousels to compensate for the fact that their items are more closely spaced and so must be dragged further to move the same distance. You cannot set this property directly, but you can override the default value by implementing the carouselOffsetMultiplier: delegate method.
@property (nonatomic, readonly) NSInteger currentItemIndex;
The index of the currently centered item in the carousel (read only). To change this, use the scrollToItemAtIndex: methods.
@property (nonatomic, retain, readonly) UIView *currentItemView;
The currently centered item view in the carousel. The index of this view matches currentItemIndex.
@property (nonatomic, readonly) CGFloat itemWidth;
The display width of items in the carousel (read only). This is derived automatically from the first view passed in to the carousel using the carousel:viewForItemAtIndex:reusingView: dataSource method. You can also override this value using the carouselItemWidth: delegate method, which will alter the spacing between carousel items (but won't resize or scale the item views).
@property (nonatomic, assign) BOOL centerItemWhenSelected;
When set to YES, tapping any item in the carousel other than the one matching the currentItemIndex will cause it to smoothly animate to the center. Tapping the currently selected item will have no effect. Defaults to YES. This property is currently only supported on the iOS version of iCarousel.
@property (nonatomic, assign) CGFloat scrollSpeed;
This is the scroll speed multiplier when the user flicks the carousel with their finger. Defaults to 1.0.
@property (nonatomic, readonly) CGFloat toggle;
This property is used for the iCarouselTypeCoverFlow2 carousel transform. It is exposed so that you can implement your own variants of the CoverFlow2 style using the carousel:itemTransformForOffset:baseTransform: delegate method.
@property (nonatomic, assign) BOOL stopAtItemBoundary;
By default, the carousel will come to rest at an exact item boundary when it is flicked. If you set this property to NO, it will stop naturally and then - if scrollToItemBoundary is set to YES - scroll back or forwards to the nearest boundary.
@property (nonatomic, assign) BOOL scrollToItemBoundary;
By default whenever the carousel stops moving it will automatically scroll to the nearest item boundary. If you set this property to NO, the carousel will not scroll after stopping and will stay wherever it is, even if it's not perfectly aligned on the current index. The exception to this is that if wrapping is disabled and bounces is set to YES then regardless of this setting, the carousel will automatically scroll back to the first or last item index if it comes to rest beyond the end of the carousel.
@property (nonatomic, assign) BOOL useDisplayLink;
By default on iOS iCarousel will use CADisplayLink instead of NSTimer for animations. On Mac OS, the CVDisplayLink API is used instead. This provides better synchronisation with the screen refresh, but can occasionally prevent the animation working properly when the carousel is combined with other views or animations. If you find that the carousel is not continuing to move after being dragged, try setting this property to NO.
@property (nonatomic, assign, getter = isVertical) BOOL vertical;
This property toggles whether the carousel is displayed horizontally or vertically on screen. All the built-in carousel types work in both orientations. Switching to vertical changes both the layout of the carousel and also the direction of swipe detection on screen. Note that custom carousel transforms are not affected by this property, however the swipe gesture direction will still be affected.
@property (nonatomic, assign) BOOL ignorePerpendicularSwipes;
If YES, the carousel will ignore swipe gestures that are perpendicular to the orientation of the carousel. So for a horizontal carousel, vertical swipes will not be intercepted. This means that you can have a vertically scrolling scrollView inside a carousel item view and it will still function correctly. Defaults to YES.
@property (nonatomic, assign) BOOL clipToBounds;
This is actually not a property of iCarousel but is inherited from UIView. It's included here because it's a frequently missed feature. Set this to YES to prevent the carousel item views overflowing their bounds. You can set this property in Interface Builder by ticking the 'Clip Subviews' option. Defaults to NO.
More item by nicklockwood
iVersion
CountryPicker
ReflectionView