Pregunta

I want to create UIScrollView with scrolling buttons.So when user press left arrow button, scroll must scroll properly.

The issue is: when I click button 3 times quickly scroll can't scroll properly (because of many calls of scrollRectToVisible). May be I can stop current animation before next animation?

P.S. If I set [self scrollScrollViewToIndex:index animated:NO] everything works properly, but I need animation

Here is my code:

- (void)scrollScrollViewToIndex:(int)index animated:(BOOL)animated
{
    NSLog(@"scrolled to index: %d", index);
    CGFloat offsetX = CGRectGetWidth(_scrollMain.frame) * index;
    CGRect scrollRect = CGRectMake(offsetX, 0, CGRectGetWidth(_scrollMain.frame), CGRectGetHeight(_scrollMain.frame));    
    [_scrollMain scrollRectToVisible:scrollRect animated:animated];
//    [self.scrollMain setContentOffset:CGPointMake(offsetX, 0) animated:animated];
}

- (IBAction)leftArrowPressed:(id)sender
{
    int indexOfVoucher = [_arrayVouchers indexOfObject:_voucher];
    indexOfVoucher--;
    self.voucher = [_arrayVouchers objectAtIndex:indexOfVoucher];
    [self updateViewWithVoucherWithScrolling:YES];
}

- (IBAction)rightArrowPressed:(id)sender
{
    int indexOfVoucher = [_arrayVouchers indexOfObject:_voucher];
    indexOfVoucher++;
    self.voucher = [_arrayVouchers objectAtIndex:indexOfVoucher];
    [self updateViewWithVoucherWithScrolling:YES];
}

- (void)updateViewWithVoucherWithScrolling:(BOOL)withScrolling
{
    int indexOfVoucher = [_arrayVouchers indexOfObject:_voucher];
    _leftArrowButton.hidden = _rightArrowButton.hidden = NO;
    if (indexOfVoucher == 0)
    {
        _leftArrowButton.hidden = YES;
    }
    else if (indexOfVoucher == [_arrayVouchers count] - 1)
    {
        self.rightArrowButton.hidden = YES;
    }
    if (withScrolling)
    {
       [self scrollScrollViewToIndex:indexOfVoucher animated:YES]; 
    }
}

update: working code according to Mar0ux's advice

- (void)scrollScrollViewToIndex:(int)index animated:(BOOL)animated
{
    NSLog(@"scrolled to index: %d", index);
    CGFloat offsetX = CGRectGetWidth(_scrollMain.frame) * index;

    if (animated)
    {
        [UIView animateWithDuration:0.5
                              delay:0.0
                            options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState //Multiple options
                         animations:^ {
                             //                         [self.scrollMain setContentOffset:CGPointMake(offsetX, 0) animated:NO];
                             CGRect scrollRect = CGRectMake(offsetX, 0, CGRectGetWidth(_scrollMain.frame), CGRectGetHeight(_scrollMain.frame));
                             [_scrollMain scrollRectToVisible:scrollRect animated:NO];
                         }
                         completion:^ (BOOL finished) {

                         }];
    }
    else
    {
        CGRect scrollRect = CGRectMake(offsetX, 0, CGRectGetWidth(_scrollMain.frame), CGRectGetHeight(_scrollMain.frame));
        [_scrollMain scrollRectToVisible:scrollRect animated:NO];
    }
}
¿Fue útil?

Solución

You can always animate the contentOffset property yourself and use UIViewAnimationOptionBeginFromCurrentState option. As soon as the second animation begins, the first will end, and by using current state option, the second animation will start from where the first left off.

Otros consejos

A few suggestions:

1) do you really want the user hammering on the button while its scrolling? If so then I suggest that your UI design may need redesign.

2) when you perturb the UI in an action method, its best to post other UI actions by dispatching a block with the code to the main queue - the button hiliting will look better.

3) in your specific case, you could in the action method disable the button, then re-enable it when the scrolling has stopped.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top