Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updated iCarousel to version 1.5.3

  • Loading branch information...
commit ae2d5714b43dc0939168d8916e6856cad745f3a0 1 parent 0f39bb2
@nicklockwood nicklockwood authored Nick Lockwood committed
View
2  LICENCE.md
@@ -1,5 +1,5 @@
iCarousel
-version 1.5.2, August 2nd, 2011
+version 1.5.3, August 11th, 2011
Copyright (C) 2011 Charcoal Design
View
46 README.md
@@ -48,7 +48,7 @@ An object that supports the iCarouselDelegate protocol and can respond to carous
Used to switch the carousel display type (see above for details).
- @property (nonatomic, assign) float perspective;
+ @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;
@@ -62,7 +62,7 @@ This property is used to adjust the user viewpoint relative to the carousel item
Note that the viewpointOffset transform is concatenated with the carousel item transform used by the carousel (or the custom transform you have supplied using the transformForItemView delegate method), so if the carousel items are rotated or scaled then this may not have the desired effect.
- @property (nonatomic, assign) float decelerationRate;
+ @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).
@@ -70,7 +70,7 @@ The rate at which the carousel decelerates when flicked. Higher values mean slow
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) float bounceDistance;
+ @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;
@@ -82,6 +82,14 @@ Enables and disables user scrolling of the carousel. The carousel can still be s
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, readonly) NSSet *visibleViews;
A set of all the item views currently displayed in the carousel (read only). The order of these views is arbitrary, and does not relate to the item indices.
@@ -90,11 +98,19 @@ A set of all the item views currently displayed in the carousel (read only). The
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 currently centered item in the carousel (read only). To change this, use the `scrollToItemAtIndex:` methods.
- @property (nonatomic, readonly) float itemWidth;
+ @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:` 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).
@@ -102,15 +118,11 @@ The display width of items in the carousel (read only). This is derived automati
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) NSInteger numberOfVisibleItems;
-
-This is the maximum number of item views that should be visible in the carousel at once. Half of this number of views will be displayed to either side of the currently selected item index. Views beyond that will not be loaded until they are scrolled into view. This allows for the carousel to contain a very large number of items without adversely affecting performance. The numberOfVisibleItems should be a positive, odd number, and defaults to 21.
-
- @property (nonatomic, readonly) float scrollSpeed;
+ @property (nonatomic, assign) CGFloat scrollSpeed;
-This is the scroll speed multiplier when the user drags the carousel with their finger (read only). By default this is 1.0 for most carousel types, but defaults to 4.0 for the CoverFlow-style carousels to compensate for the fact that their items are more closely spaced. To change the default scrollSpeed, implement the `carouselScrollSpeed:` delegate method.
+This is the scroll speed multiplier when the user flicks the carousel with their finger. Defaults to 1.0.
- @property (nonatomic, readonly) float toggle;
+ @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:transformForItemView:withOffset` delegate method.
@@ -176,6 +188,10 @@ Returns the number of placeholder views to display in the carousel. Placeholder
Return a view to be displayed as the placeholder view. As with the regular item views, you must return a unique view instance for each call to `carouselPlaceholderView:` to avoid display issues. **Note: the protocol and behaviour for placeholders has changed since version 1.2.x - they are no longer mirrored, so it is possible to provide visually distinct views for each placeholder.**
+ - (NSUInteger)numberOfVisibleItemsInCarousel:(iCarousel *)carousel;
+
+This is the maximum number of item views (including placeholders) that should be visible in the carousel at once. Half of this number of views will be displayed to either side of the currently selected item index. Views beyond that will not be loaded until they are scrolled into view. This allows for the carousel to contain a very large number of items without adversely affecting performance. The numberOfVisibleItems should be a positive, odd number. If this method is not implemented, all item views and placeholder views will be drawn every frame, which will result in significant degrading in performance and increased memory usage for large numbers of items (e.g more than 50).
+
The iCarouselDelegate protocol has the following optional methods:
- (void)carouselWillBeginScrollingAnimation:(iCarousel *)carousel;
@@ -210,19 +226,19 @@ This method is called when the carousel starts decelerating. it will typically b
This method is called when the carousel finishes decelerating and you can assume that the currentItemIndex at this point is the final stopping value. Unlike previous versions, the carousel will now stop exactly on the final index position in most cases. The only exception is on non-wrapped carousels with bounce enabled, where, if the final stopping position is beyond the end of the carousel, the carousel will then scroll automatically until it aligns exactly on the end index. For backwards compatibility, the carousel will always call `scrollToItemAtIndex:animated:` after it finishes decelerating. If you need to know for certain when the carousel has stopped moving completely, use the `carouselDidEndScrollingAnimation` delegate method.
- - (float)carouselItemWidth:(iCarousel *)carousel;
+ - (CGFloat)carouselItemWidth:(iCarousel *)carousel;
Returns the width of each item in the carousel - i.e. the spacing for each item view. If the method is not implemented, this defaults to the width of the first item view that is returned by the `carousel:viewForItemAtIndex:` dataSource method.
- - (float)carouseScrollSpeed:(iCarousel *)carousel;
+ - (CGFloat)carouseOffsetMultiplier:(iCarousel *)carousel;
-Returns the scroll speed multiplier when the user drags the carousel with their finger. It does not affect programmatic scrolling or deceleration speed. If the method is not implemented, this defaults to 1.0 for most carousel types, but defaults to 4.0 for the CoverFlow-style carousels to compensate for the fact that their items are more closely spaced.
+Returns the offset multiplier to use when the user drags the carousel with their finger. It does not affect programmatic scrolling or deceleration speed. If the method is not implemented, 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.
- (BOOL)carouselShouldWrap:(iCarousel *)carousel;
Return YES if you want the carousel to wrap around when it reaches the end, and no if you want it to stop. If you do not implement this method, wrapping will be enabled or disabled depending on the carousel type. Generally, circular carousel types will wrap by default and linear ones won't.
- - (CATransform3D)carousel:(iCarousel *)carousel transformForItemView:(UIView *)view withOffset:(float)offset;
+ - (CATransform3D)carousel:(iCarousel *)carousel transformForItemView:(UIView *)view withOffset:(CGFloat)offset;
This method can be used to provide a custom transform for each carousel view. The offset argument is the distance of the view from the middle of the carousel. The currently centered item view would have an offset of 0, the one to the right would have an offset value of 1.0, the one to the left an offset value of -1.0, and so on. To implement the linear carousel style, you would therefore simply multiply the offset value by the item width and use it as the x value of the transform. If you need to manipulate the view in other ways as it scrolls, such as settings its alpha opacity, you can manipulate the view property directly. Manipulating the view frame, center or bounds is not recommended as the effect may be unpredictable and subject to undocumented change in future releases.
View
11 RELEASE NOTES.md
@@ -1,3 +1,14 @@
+Version 1.5.3
+
+- Fixed a bug on wrapped carousels when the total number of carousel items exceeds the number of visible items.
+- Changed numberOfVisibleItems property to be a dataSource method, removing the arbitrary default limit of 21.
+- Fixed a flickering issue on CoverFlow2 carousel type.
+- Fixed bug on Mac where clicking would spin the carousel a random distance.
+- scrollSpeed is now a read/write property, and only affects speed when carousel is flicked.
+- Removed `carouselScrollSpeed` delegate method and replaced it with new `offsetMultiplier` property and `carouselOffsetMultiplier` delegate method to control the offset when dragging.
+- scrollOffset property is now public (readonly).
+- Floating point arguments and properties are now CGFloats instead of floats.
+
Version 1.5.2
- Added bounceDistance property for finer control over bounce behaviour.
View
6 iCarousel Mac Demo/iCarouselMac/iCarouselWindowController.m
@@ -144,6 +144,12 @@ - (NSView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)in
return view;
}
+- (NSUInteger)numberOfVisibleItemsInCarousel:(iCarousel *)carousel
+{
+ //limit the number of items views loaded concurrently (for performance reasons)
+ return 21;
+}
+
- (float)carouselItemWidth:(iCarousel *)carousel
{
//slightly wider than item view
View
2  iCarousel iOS Demo/iCarouselExample-Info.plist
@@ -34,5 +34,7 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
+ <key>UIStatusBarHidden</key>
+ <true/>
</dict>
</plist>
View
6 iCarousel iOS Demo/iCarouselExampleViewController.m
@@ -182,6 +182,12 @@ - (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)in
return view;
}
+- (NSUInteger)numberOfVisibleItemsInCarousel:(iCarousel *)carousel
+{
+ //limit the number of items views loaded concurrently (for performance reasons)
+ return 21;
+}
+
- (float)carouselItemWidth:(iCarousel *)carousel
{
//slightly wider than item view
View
48 iCarousel/iCarousel.h
@@ -1,7 +1,7 @@
//
// iCarousel.h
//
-// Version 1.5.2
+// Version 1.5.3
//
// Created by Nick Lockwood on 01/04/2011.
// Copyright 2010 Charcoal Design. All rights reserved.
@@ -61,7 +61,7 @@ iCarouselType;
id<iCarouselDelegate> delegate;
id<iCarouselDataSource> dataSource;
iCarouselType type;
- float perspective;
+ CGFloat perspective;
NSInteger numberOfItems;
NSInteger numberOfPlaceholders;
NSInteger numberOfPlaceholdersToShow;
@@ -69,29 +69,30 @@ iCarouselType;
UIView *contentView;
NSDictionary *itemViews;
NSInteger previousItemIndex;
- float itemWidth;
- float scrollOffset;
- float startVelocity;
+ CGFloat itemWidth;
+ CGFloat scrollOffset;
+ CGFloat offsetMultiplier;
+ CGFloat startVelocity;
id timer;
BOOL decelerating;
BOOL scrollEnabled;
- float decelerationRate;
+ CGFloat decelerationRate;
BOOL bounces;
CGSize contentOffset;
CGSize viewpointOffset;
- float startOffset;
- float endOffset;
+ CGFloat startOffset;
+ CGFloat endOffset;
NSTimeInterval scrollDuration;
NSTimeInterval startTime;
BOOL scrolling;
- float previousTranslation;
+ CGFloat previousTranslation;
BOOL centerItemWhenSelected;
BOOL shouldWrap;
BOOL dragging;
- float scrollSpeed;
- float bounceDistance;
+ CGFloat scrollSpeed;
+ CGFloat bounceDistance;
NSTimeInterval toggleTime;
- float toggle;
+ CGFloat toggle;
BOOL stopAtItemBoundary;
BOOL scrollToItemBoundary;
}
@@ -100,22 +101,24 @@ iCarouselType;
@property (nonatomic, assign) IBOutlet id<iCarouselDataSource> dataSource;
@property (nonatomic, assign) IBOutlet id<iCarouselDelegate> delegate;
@property (nonatomic, assign) iCarouselType type;
-@property (nonatomic, assign) float perspective;
-@property (nonatomic, assign) float decelerationRate;
-@property (nonatomic, assign) float bounceDistance;
+@property (nonatomic, assign) CGFloat perspective;
+@property (nonatomic, assign) CGFloat decelerationRate;
+@property (nonatomic, assign) CGFloat scrollSpeed;
+@property (nonatomic, assign) CGFloat bounceDistance;
@property (nonatomic, assign) BOOL scrollEnabled;
@property (nonatomic, assign) BOOL bounces;
+@property (nonatomic, readonly) CGFloat scrollOffset;
+@property (nonatomic, readonly) CGFloat offsetMultiplier;
@property (nonatomic, assign) CGSize contentOffset;
@property (nonatomic, assign) CGSize viewpointOffset;
@property (nonatomic, readonly) NSInteger numberOfItems;
@property (nonatomic, readonly) NSInteger numberOfPlaceholders;
@property (nonatomic, readonly) NSInteger currentItemIndex;
-@property (nonatomic, assign) NSInteger numberOfVisibleItems;
+@property (nonatomic, readonly) NSInteger numberOfVisibleItems;
@property (nonatomic, retain, readonly) NSSet *visibleViews;
-@property (nonatomic, readonly) float itemWidth;
+@property (nonatomic, readonly) CGFloat itemWidth;
@property (nonatomic, retain, readonly) UIView *contentView;
-@property (nonatomic, readonly) float scrollSpeed;
-@property (nonatomic, readonly) float toggle;
+@property (nonatomic, readonly) CGFloat toggle;
@property (nonatomic, assign) BOOL stopAtItemBoundary;
@property (nonatomic, assign) BOOL scrollToItemBoundary;
@@ -144,6 +147,7 @@ iCarouselType;
- (NSUInteger)numberOfPlaceholdersInCarousel:(iCarousel *)carousel;
- (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)index;
+- (NSUInteger)numberOfVisibleItemsInCarousel:(iCarousel *)carousel;
@end
@@ -160,10 +164,10 @@ iCarouselType;
- (void)carouselDidEndDragging:(iCarousel *)carousel willDecelerate:(BOOL)decelerate;
- (void)carouselWillBeginDecelerating:(iCarousel *)carousel;
- (void)carouselDidEndDecelerating:(iCarousel *)carousel;
-- (float)carouselItemWidth:(iCarousel *)carousel;
-- (float)carouselScrollSpeed:(iCarousel *)carousel;
+- (CGFloat)carouselItemWidth:(iCarousel *)carousel;
+- (CGFloat)carouselOffsetMultiplier:(iCarousel *)carousel;
- (BOOL)carouselShouldWrap:(iCarousel *)carousel;
-- (CATransform3D)carousel:(iCarousel *)carousel transformForItemView:(UIView *)view withOffset:(float)offset;
+- (CATransform3D)carousel:(iCarousel *)carousel transformForItemView:(UIView *)view withOffset:(CGFloat)offset;
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
View
181 iCarousel/iCarousel.m
@@ -1,7 +1,7 @@
//
// iCarousel.m
//
-// Version 1.5.2
+// Version 1.5.3
//
// Created by Nick Lockwood on 01/04/2011.
// Copyright 2010 Charcoal Design. All rights reserved.
@@ -33,6 +33,8 @@
#import "iCarousel.h"
+#define MIN_TOGGLE_DURATION 0.2f
+#define MAX_TOGGLE_DURATION 0.4f
#define SCROLL_DURATION 0.4f
#define INSERT_DURATION 0.4f
#define DECELERATE_THRESHOLD 0.1f
@@ -51,26 +53,27 @@ @interface iCarousel ()
@property (nonatomic, retain) NSDictionary *itemViews;
@property (nonatomic, assign) NSInteger previousItemIndex;
@property (nonatomic, assign) NSInteger numberOfPlaceholdersToShow;
-@property (nonatomic, assign) float itemWidth;
-@property (nonatomic, assign) float scrollOffset;
-@property (nonatomic, assign) float startOffset;
-@property (nonatomic, assign) float endOffset;
+@property (nonatomic, assign) NSInteger numberOfVisibleItems;
+@property (nonatomic, assign) CGFloat itemWidth;
+@property (nonatomic, assign) CGFloat scrollOffset;
+@property (nonatomic, assign) CGFloat offsetMultiplier;
+@property (nonatomic, assign) CGFloat startOffset;
+@property (nonatomic, assign) CGFloat endOffset;
@property (nonatomic, assign) NSTimeInterval scrollDuration;
@property (nonatomic, assign) BOOL scrolling;
@property (nonatomic, assign) NSTimeInterval startTime;
-@property (nonatomic, assign) float startVelocity;
+@property (nonatomic, assign) CGFloat startVelocity;
@property (nonatomic, assign) id timer;
@property (nonatomic, assign) BOOL decelerating;
-@property (nonatomic, assign) float previousTranslation;
+@property (nonatomic, assign) CGFloat previousTranslation;
@property (nonatomic, assign) BOOL shouldWrap;
@property (nonatomic, assign) BOOL dragging;
-@property (nonatomic, assign) float scrollSpeed;
@property (nonatomic, assign) NSTimeInterval toggleTime;
- (void)layOutItemViews;
- (UIView *)loadViewAtIndex:(NSInteger)index;
- (NSInteger)clampedIndex:(NSInteger)index;
-- (float)clampedOffset:(float)offset;
+- (CGFloat)clampedOffset:(CGFloat)offset;
- (void)transformItemView:(UIView *)view atIndex:(NSInteger)index;
- (void)startAnimation;
- (void)stopAnimation;
@@ -94,6 +97,7 @@ @implementation iCarousel
@synthesize previousItemIndex;
@synthesize itemWidth;
@synthesize scrollOffset;
+@synthesize offsetMultiplier;
@synthesize startVelocity;
@synthesize timer;
@synthesize decelerating;
@@ -134,9 +138,9 @@ - (void)setup
scrollEnabled = YES;
bounces = YES;
scrollOffset = 0.0f;
+ offsetMultiplier = 1.0f;
contentOffset = CGSizeZero;
viewpointOffset = CGSizeZero;
- numberOfVisibleItems = 21;
shouldWrap = NO;
scrollSpeed = 1.0f;
bounceDistance = 1.0f;
@@ -311,7 +315,7 @@ - (NSInteger)indexOfView:(UIView *)view
#pragma mark -
#pragma mark View layout
-- (CATransform3D)transformForItemView:(UIView *)view withOffset:(float)offset
+- (CATransform3D)transformForItemView:(UIView *)view withOffset:(CGFloat)offset
{
//set up base transform
CATransform3D transform = CATransform3DIdentity;
@@ -329,9 +333,9 @@ - (CATransform3D)transformForItemView:(UIView *)view withOffset:(float)offset
{
NSInteger count = numberOfItems + (shouldWrap? 0: numberOfPlaceholdersToShow);
- float arc = M_PI * 2.0f;
- float radius = itemWidth / 2.0f / tanf(arc/2.0f/count);
- float angle = offset / count * arc;
+ CGFloat arc = M_PI * 2.0f;
+ CGFloat radius = itemWidth / 2.0f / tanf(arc/2.0f/count);
+ CGFloat angle = offset / count * arc;
if (type == iCarouselTypeInvertedRotary)
{
@@ -347,9 +351,9 @@ - (CATransform3D)transformForItemView:(UIView *)view withOffset:(float)offset
{
NSInteger count = numberOfItems + (shouldWrap? 0: numberOfPlaceholdersToShow);
- float arc = M_PI * 2.0f;
- float radius = itemWidth / 2.0f / tanf(arc/2.0f/count);
- float angle = offset / count * arc;
+ CGFloat arc = M_PI * 2.0f;
+ CGFloat radius = itemWidth / 2.0f / tanf(arc/2.0f/count);
+ CGFloat angle = offset / count * arc;
if (type == iCarouselTypeInvertedCylinder)
{
@@ -365,23 +369,23 @@ - (CATransform3D)transformForItemView:(UIView *)view withOffset:(float)offset
case iCarouselTypeCoverFlow:
case iCarouselTypeCoverFlow2:
{
- float tilt = 0.9f;
- float spacing = 0.25f; // should be ~ 1/scrollSpeed;
- float clampedOffset = fmaxf(-1.0f, fminf(1.0f, offset));
+ CGFloat tilt = 0.9f;
+ CGFloat spacing = 0.25f; // should be ~ 1/scrollSpeed;
+ CGFloat clampedOffset = fmaxf(-1.0f, fminf(1.0f, offset));
if (type == iCarouselTypeCoverFlow2)
{
if (toggle >= 0.0f)
{
- if (offset < -0.5f)
+ if (offset <= -0.5f)
{
clampedOffset = -1.0f;
}
- else if (offset < 0.5f)
+ else if (offset <= 0.5f)
{
clampedOffset = -toggle;
}
- else if (offset < 1.5f)
+ else if (offset <= 1.5f)
{
clampedOffset = 1.0f - toggle;
}
@@ -403,8 +407,8 @@ - (CATransform3D)transformForItemView:(UIView *)view withOffset:(float)offset
}
}
- float x = (clampedOffset * 0.5f * tilt + offset * spacing) * itemWidth;
- float z = fabsf(clampedOffset) * -itemWidth * 0.5f;
+ CGFloat x = (clampedOffset * 0.5f * tilt + offset * spacing) * itemWidth;
+ CGFloat z = fabsf(clampedOffset) * -itemWidth * 0.5f;
transform = CATransform3DTranslate(transform, x, 0.0f, z);
return CATransform3DRotate(transform, -clampedOffset * M_PI_2 * tilt, 0.0f, 1.0f, 0.0f);
}
@@ -421,15 +425,15 @@ NSInteger compareViewDepth(id obj1, id obj2, void *context)
iCarousel *carousel = context;
CATransform3D t1 = ((UIView *)obj1).superview.layer.transform;
CATransform3D t2 = ((UIView *)obj2).superview.layer.transform;
- float z1 = t1.m13 + t1.m23 + t1.m33 + t1.m43;
- float z2 = t2.m13 + t2.m23 + t2.m33 + t2.m43;
- float difference = z1 - z2;
+ CGFloat z1 = t1.m13 + t1.m23 + t1.m33 + t1.m43;
+ CGFloat z2 = t2.m13 + t2.m23 + t2.m33 + t2.m43;
+ CGFloat difference = z1 - z2;
if (difference == 0.0f)
{
CATransform3D t3 = [carousel currentView].superview.layer.transform;
- float x1 = t1.m11 + t1.m21 + t1.m31 + t1.m41;
- float x2 = t2.m11 + t2.m21 + t2.m31 + t2.m41;
- float x3 = t3.m11 + t3.m21 + t3.m31 + t3.m41;
+ CGFloat x1 = t1.m11 + t1.m21 + t1.m31 + t1.m41;
+ CGFloat x2 = t2.m11 + t2.m21 + t2.m31 + t2.m41;
+ CGFloat x3 = t3.m11 + t3.m21 + t3.m31 + t3.m41;
difference = fabsf(x2 - x3) - fabsf(x1 - x3);
}
return (difference < 0.0f)? NSOrderedAscending: NSOrderedDescending;
@@ -449,11 +453,11 @@ - (void)depthSortViews
}
-- (float)offsetForIndex:(NSInteger)index
+- (CGFloat)offsetForIndex:(NSInteger)index
{
//calculate relative position
- float itemOffset = scrollOffset / itemWidth;
- float offset = index - itemOffset;
+ CGFloat itemOffset = scrollOffset / itemWidth;
+ CGFloat offset = index - itemOffset;
if (shouldWrap)
{
if (offset > numberOfItems/2)
@@ -507,8 +511,8 @@ - (void)transformItemView:(UIView *)view atIndex:(NSInteger)index
#endif
//special-case logic for iCarouselTypeCoverFlow2
- float offset = [self offsetForIndex:index];
- float clampedOffset = fmaxf(-1.0f, fminf(1.0f, offset));
+ CGFloat offset = [self offsetForIndex:index];
+ CGFloat clampedOffset = fmaxf(-1.0f, fminf(1.0f, offset));
if (decelerating || (scrollOffset - [self clampedOffset:scrollOffset]) != 0.0f)
{
if (offset > 0)
@@ -571,7 +575,7 @@ - (void)layOutItemViews
}
//record current item width
- float prevItemWidth = itemWidth;
+ CGFloat prevItemWidth = itemWidth;
//update wrap
if ([delegate respondsToSelector:@selector(carouselShouldWrap:)])
@@ -615,10 +619,10 @@ - (void)layOutItemViews
itemWidth = [[[itemViews allValues] lastObject] bounds].size.width;
}
- //update scroll speed
- if ([delegate respondsToSelector:@selector(carouselScrollSpeed:)])
+ //update offset multiplier
+ if ([delegate respondsToSelector:@selector(carouselOffsetMultiplier:)])
{
- scrollSpeed = [delegate carouselScrollSpeed:self];
+ offsetMultiplier = [delegate carouselOffsetMultiplier:self];
}
else
{
@@ -627,12 +631,12 @@ - (void)layOutItemViews
case iCarouselTypeCoverFlow:
case iCarouselTypeCoverFlow2:
{
- scrollSpeed = 4.0f;
+ offsetMultiplier = 2.0f;
break;
}
default:
{
- scrollSpeed = 1.0f;
+ offsetMultiplier = 1.0f;
break;
}
}
@@ -665,7 +669,7 @@ - (UIView *)loadViewAtIndex:(NSInteger)index
UIView *view = nil;
if (index < 0)
{
- view = [dataSource carousel:self placeholderViewAtIndex:(int)ceilf((float)numberOfPlaceholdersToShow/2.0f) + index];
+ view = [dataSource carousel:self placeholderViewAtIndex:(int)ceilf((CGFloat)numberOfPlaceholdersToShow/2.0f) + index];
}
else if (index >= numberOfItems)
{
@@ -692,14 +696,22 @@ - (void)loadUnloadViews
{
//calculate visible view indices
NSMutableSet *visibleIndices = [NSMutableSet setWithCapacity:numberOfVisibleItems];
- NSInteger min = -(int)ceilf((float)numberOfPlaceholdersToShow/2.0f);
+ NSInteger min = -(int)ceilf((CGFloat)numberOfPlaceholdersToShow/2.0f);
NSInteger max = numberOfItems - 1 + numberOfPlaceholdersToShow/2;
NSInteger count = MIN(numberOfVisibleItems, numberOfItems + numberOfPlaceholdersToShow);
NSInteger offset = self.currentItemIndex - numberOfVisibleItems/2;
- offset = MAX(min, MIN(max - count + 1, offset));
+ if (!shouldWrap)
+ {
+ offset = MAX(min, MIN(max - count + 1, offset));
+ }
for (NSInteger i = 0; i < count; i++)
{
- [visibleIndices addObject:[NSNumber numberWithInteger:i + offset]];
+ NSInteger index = i + offset;
+ if (shouldWrap)
+ {
+ index = [self clampedIndex:index];
+ }
+ [visibleIndices addObject:[NSNumber numberWithInteger:index]];
}
//remove offscreen views
@@ -745,6 +757,13 @@ - (void)reloadData
{
numberOfPlaceholders = [dataSource numberOfPlaceholdersInCarousel:self];
}
+
+ //get number of visible items
+ numberOfVisibleItems = numberOfItems + numberOfPlaceholders;
+ if ([dataSource respondsToSelector:@selector(numberOfVisibleItemsInCarousel:)])
+ {
+ numberOfVisibleItems = [dataSource numberOfVisibleItemsInCarousel:self];
+ }
//layout views
[CATransaction setDisableActions:YES];
@@ -768,7 +787,7 @@ - (NSInteger)clampedIndex:(NSInteger)index
{
return 0;
}
- return index - floorf((float)index / (float)numberOfItems) * numberOfItems;
+ return index - floorf((CGFloat)index / (CGFloat)numberOfItems) * numberOfItems;
}
else
{
@@ -776,7 +795,7 @@ - (NSInteger)clampedIndex:(NSInteger)index
}
}
-- (float)clampedOffset:(float)offset
+- (CGFloat)clampedOffset:(CGFloat)offset
{
if (shouldWrap)
{
@@ -784,7 +803,7 @@ - (float)clampedOffset:(float)offset
{
return 0;
}
- float contentWidth = numberOfItems * itemWidth;
+ CGFloat contentWidth = numberOfItems * itemWidth;
return offset - floorf(offset / contentWidth) * contentWidth;
}
else
@@ -813,12 +832,12 @@ - (NSInteger)minScrollDistanceFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)
return directDistance;
}
-- (float)minScrollDistanceFromOffset:(float)fromOffset toOffset:(float)toOffset
+- (CGFloat)minScrollDistanceFromOffset:(CGFloat)fromOffset toOffset:(CGFloat)toOffset
{
- float directDistance = toOffset - fromOffset;
+ CGFloat directDistance = toOffset - fromOffset;
if (shouldWrap)
{
- float wrappedDistance = fminf(toOffset, fromOffset) + numberOfItems*itemWidth - fmaxf(toOffset, fromOffset);
+ CGFloat wrappedDistance = fminf(toOffset, fromOffset) + numberOfItems*itemWidth - fmaxf(toOffset, fromOffset);
if (fromOffset < toOffset)
{
wrappedDistance = -wrappedDistance;
@@ -902,6 +921,10 @@ - (void)removeItemAtIndex:(NSInteger)index animated:(BOOL)animated
[UIView setAnimationDidStopSelector:@selector(depthSortViews)];
[self removeViewAtIndex:index];
numberOfItems --;
+ if (![dataSource respondsToSelector:@selector(numberOfVisibleItemsInCarousel:)])
+ {
+ numberOfVisibleItems --;
+ }
scrollOffset = itemWidth * self.currentItemIndex;
[self didScroll];
[UIView commitAnimations];
@@ -968,6 +991,10 @@ - (void)insertItemAtIndex:(NSInteger)index animated:(BOOL)animated
{
index = [self clampedIndex:index];
numberOfItems ++;
+ if (![dataSource respondsToSelector:@selector(numberOfVisibleItemsInCarousel:)])
+ {
+ numberOfVisibleItems ++;
+ }
[self insertView:nil atIndex:index];
UIView *itemView = [self loadViewAtIndex:index];
@@ -1039,9 +1066,9 @@ - (void)stopAnimation
timer = nil;
}
-- (float)decelerationDistance
+- (CGFloat)decelerationDistance
{
- float acceleration = -startVelocity * DECELERATION_MULTIPLIER * (1.0f - decelerationRate);
+ CGFloat acceleration = -startVelocity * DECELERATION_MULTIPLIER * (1.0f - decelerationRate);
return -powf(startVelocity, 2.0f) / (2.0f * acceleration);
}
@@ -1059,7 +1086,7 @@ - (BOOL)shouldScroll
- (void)startDecelerating
{
- float distance = [self decelerationDistance];
+ CGFloat distance = [self decelerationDistance];
startOffset = scrollOffset;
endOffset = startOffset + distance;
if (stopAtItemBoundary)
@@ -1097,7 +1124,7 @@ - (void)startDecelerating
}
}
-- (float)easeInOut:(float)time
+- (CGFloat)easeInOut:(CGFloat)time
{
return (time < 0.5f)? 0.5f * powf(time * 2.0f, 3.0f): 0.5f * powf(time * 2.0f - 2.0f, 3.0f) + 1.0f;
}
@@ -1109,9 +1136,10 @@ - (void)step
if (toggle != 0.0f)
{
- float toggleDuration = SCROLL_DURATION * fminf(1.0f, fmaxf(0.0f, itemWidth / fabsf(startVelocity)));
+ CGFloat toggleDuration = fminf(1.0f, fmaxf(0.0f, itemWidth / fabsf(startVelocity)));
+ toggleDuration = MIN_TOGGLE_DURATION + (MAX_TOGGLE_DURATION - MIN_TOGGLE_DURATION) * toggleDuration;
NSTimeInterval time = fminf(1.0f, (currentTime - toggleTime) / toggleDuration);
- float delta = [self easeInOut:time];
+ CGFloat delta = [self easeInOut:time];
toggle = (toggle < 0.0f)? (delta - 1.0f): (1.0f - delta);
[self didScroll];
}
@@ -1119,7 +1147,7 @@ - (void)step
if (scrolling)
{
NSTimeInterval time = fminf(1.0f, (currentTime - startTime) / scrollDuration);
- float delta = [self easeInOut:time];
+ CGFloat delta = [self easeInOut:time];
scrollOffset = startOffset + (endOffset - startOffset) * delta;
[self didScroll];
if (time == 1.0f)
@@ -1134,13 +1162,13 @@ - (void)step
}
else if (decelerating)
{
- float time = fminf(scrollDuration, currentTime - startTime);
- float acceleration = -startVelocity/scrollDuration;
- float distance = startVelocity * time + 0.5f * acceleration * powf(time, 2.0f);
+ CGFloat time = fminf(scrollDuration, currentTime - startTime);
+ CGFloat acceleration = -startVelocity/scrollDuration;
+ CGFloat distance = startVelocity * time + 0.5f * acceleration * powf(time, 2.0f);
scrollOffset = startOffset + distance;
[self didScroll];
- if (time == (float)scrollDuration)
+ if (time == (CGFloat)scrollDuration)
{
decelerating = NO;
if ([delegate respondsToSelector:@selector(carouselDidEndDecelerating:)])
@@ -1186,8 +1214,8 @@ - (void)didScroll
}
else
{
- float min = -bounceDistance * itemWidth;
- float max = ((float)numberOfItems - 1.0f + bounceDistance) * itemWidth;
+ CGFloat min = -bounceDistance * itemWidth;
+ CGFloat max = ((CGFloat)numberOfItems - 1.0f + bounceDistance) * itemWidth;
if (scrollOffset < min)
{
scrollOffset = min;
@@ -1206,7 +1234,7 @@ - (void)didScroll
if (difference)
{
toggleTime = CACurrentMediaTime();
- toggle = fmaxf(-1.0f, fminf(1.0f, -(float)difference));
+ toggle = fmaxf(-1.0f, fminf(1.0f, -(CGFloat)difference));
[self startAnimation];
}
@@ -1352,16 +1380,16 @@ - (void)didPan:(UIPanGestureRecognizer *)panGesture
}
default:
{
- float translation = [panGesture translationInView:self].x - previousTranslation;
- float factor = 1.0f;
+ CGFloat translation = [panGesture translationInView:self].x - previousTranslation;
+ CGFloat factor = 1.0f;
if (!shouldWrap && bounces)
{
factor = 1.0f - fminf(fabsf(scrollOffset - [self clampedOffset:scrollOffset]) / itemWidth, bounceDistance) / bounceDistance;
}
previousTranslation = [panGesture translationInView:self].x;
- startVelocity = -[panGesture velocityInView:self].x * factor;
- scrollOffset -= translation * factor * scrollSpeed;
+ startVelocity = -[panGesture velocityInView:self].x * factor * scrollSpeed;
+ scrollOffset -= translation * factor * offsetMultiplier;
[self didScroll];
}
}
@@ -1374,6 +1402,11 @@ - (void)didPan:(UIPanGestureRecognizer *)panGesture
#pragma mark -
#pragma mark Mouse control
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ startVelocity = 0.0f;
+}
+
- (void)mouseDragged:(NSEvent *)theEvent
{
if (scrollEnabled)
@@ -1389,18 +1422,18 @@ - (void)mouseDragged:(NSEvent *)theEvent
scrolling = NO;
decelerating = NO;
- float translation = [theEvent deltaX];
- float factor = 1.0f;
+ CGFloat translation = [theEvent deltaX];
+ CGFloat factor = 1.0f;
if (!shouldWrap && bounces)
{
factor = 1.0f - fminf(fabsf(scrollOffset - [self clampedOffset:scrollOffset]) / itemWidth, bounceDistance) / bounceDistance;
}
NSTimeInterval thisTime = [theEvent timestamp];
- startVelocity = -(translation / (thisTime - startTime)) * factor;
+ startVelocity = -(translation / (thisTime - startTime)) * factor * scrollSpeed;
startTime = thisTime;
- scrollOffset -= translation * factor * scrollSpeed;
+ scrollOffset -= translation * factor * offsetMultiplier;
[CATransaction setDisableActions:YES];
[self didScroll];
[CATransaction setDisableActions:NO];
Please sign in to comment.
Something went wrong with that request. Please try again.