nicklockwood / iCarousel

A simple, highly customisable, data-driven 3D carousel for iOS and Mac OS
http://www.charcoaldesign.co.uk/source/cocoa#icarousel
Other
12k stars 2.58k forks source link

Scrolling goes to wrong direction in iCarouselTypeLinear #104

Open ramrcram opened 12 years ago

ramrcram commented 12 years ago

Hi Nick, am developing an iPad application using iCarousel. first of all thanks for the wonderful component . Am facing a problem with ITEM_SPACING = 860, wrap = YES,carousel.type =iCarouselTypeLinear,ignorePerpendicularSwipes = YES. some time when we scroll from left to right or other way the item move to the wrong direction. This is what i done on viewForItemAtIndex

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
    NSString* ImageName = @"Sample.jpg";
    UIButton *button = (UIButton *)view;
    if (button == nil)
    {
        UIImage *image = [UIImage imageNamed:ImageName];
        button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = (UIDeviceOrientationIsPortrait(self.interfaceOrientation) ?CGRectMake(0,0,610,456) : CGRectMake(0,0,830,620));
        [button setBackgroundImage:image forState:UIControlStateNormal];
        [button addTarget:self action:@selector(categoryImageClicked:) forControlEvents:UIControlEventTouchUpInside];
    }    
    return button;

}

please help me to fix this problem Thanks in advance.

nicklockwood commented 12 years ago

Are all of your carousel images the same? Because if not, the code above won't work as you are recycling the same view for multiple items.

ramrcram commented 12 years ago

No ,the images are different , for the easy understand i added the like that, the actual code is getting from nsdictionary. NSString* ImageName = [carouselDic objectForKey:@"imageName"];

nicklockwood commented 12 years ago

Okay, so then your code needs to look this this:

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
    NSString* ImageName = @"Sample.jpg";
    UIButton *button = (UIButton *)view;
    if (button == nil)
    {
        button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = (UIDeviceOrientationIsPortrait(self.interfaceOrientation) ?CGRectMake(0,0,610,456) : CGRectMake(0,0,830,620));
        [button addTarget:self action:@selector(categoryImageClicked:) forControlEvents:UIControlEventTouchUpInside];
    }

    UIImage *image = [UIImage imageNamed:ImageName];
    [button setBackgroundImage:image forState:UIControlStateNormal];

    return button;
}

Views are recycled like in a tableview, so you need to set the image property each time regardless of whether there is a view available to re-use as the reusable view may have previously been set with the image for a different item in the carousel.

ramrcram commented 12 years ago

Hi Nick, i found the issue what wrong. While am scrolling it's triggering on the event

so that what i done for the fix is, just removed the default section from the switch case on didPan function and moved out side of switch now my didPan function is like :

- (void)didPan:(UIPanGestureRecognizer *)panGesture
{
if (scrollEnabled)
    {
    switch (panGesture.state)
    {
        case UIGestureRecognizerStateBegan:
        {
            dragging = YES;
            scrolling = NO;
            decelerating = NO;
            previousTranslation = vertical? [panGesture translationInView:self].y: [panGesture translationInView:self].x;
            if ([delegate respondsToSelector:@selector(carouselWillBeginDragging:)])
            {
                [delegate carouselWillBeginDragging:self];
            }
            break;
        }
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
        {
            dragging = NO;
            didDrag = YES;
            if ([self shouldDecelerate])
            {
                didDrag = NO;
                [self startDecelerating];
            }
            if ([delegate respondsToSelector:@selector(carouselDidEndDragging:willDecelerate:)])
            {
                [delegate carouselDidEndDragging:self willDecelerate:decelerating];
            }
            if (!decelerating && (scrollToItemBoundary || (scrollOffset - [self clampedOffset:scrollOffset]) != 0.0f))
            {
                if (fabsf(scrollOffset/itemWidth - self.currentItemIndex) < 0.01f)
                {
                    //call scroll to trigger events for legacy support reasons
                    //even though technically we don't need to scroll at all
                    [self scrollToItemAtIndex:self.currentItemIndex duration:0.01];
                }
                else if ([self shouldScroll])
                {
                    NSInteger direction = (int)(startVelocity / fabsf(startVelocity));
                    [self scrollToItemAtIndex:self.currentItemIndex + direction animated:YES];
                }
                else
                {
                    [self scrollToItemAtIndex:self.currentItemIndex animated:YES];
                }
            }
            else if ([delegate respondsToSelector:@selector(carouselWillBeginDecelerating:)])
            {
                [delegate carouselWillBeginDecelerating:self];
            }
            break;
        }
        default:
        {}
       }
        CGFloat translation = (vertical? [panGesture translationInView:self].y: [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 = vertical? [panGesture translationInView:self].y: [panGesture translationInView:self].x;
        startVelocity = -(vertical? [panGesture velocityInView:self].y: [panGesture velocityInView:self].x) * factor * scrollSpeed;
        scrollOffset -= translation * factor * offsetMultiplier;
        [self didScroll];   
    }
}

please let me know is anything wrong on my updated function ?

Thanks in advance Ramesh

nicklockwood commented 12 years ago

I'm not really sure why this would cause the carousel to go backwards. I'll have to check and see if I can work out if this fix has any other side effects.

ramrcram commented 12 years ago

Thanks Nick.