Подтвердить что ты не робот

UIScrollview setContentOffset с нелинейной анимацией?

Я пытаюсь воспроизвести гладкую анимацию scrollview с включенным пейджингом, когда вы действительно переходите к следующей странице. Кажется, это UIViewAnimationCurveEaseInOut, но мне нужно иметь кнопку "следующая страница" и программно прокручивать прокрутку.

Вот мой код:

-(void) scrollToPage:(int)page
{
    UIScrollView *scrollView = contentView;
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y);
    [scrollView setContentOffset:offset animated: YES];     
    [self pageControlUpdate];
}

-(void) scrollToNextPage 
{
    [self scrollToPage:(pageControl.currentPage + 1)];
}

Я не могу воспроизвести гладкость UIViewAnimationCurveEaseInOut, либо с setContentOffset, либо с помощью scrollRectToVisible... он переходит на следующую страницу с уродливой линейной анимацией

Я даже пытался анимировать его вручную:

[UIView animateWithDuration:.5 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
    scrollView.contentOffset = offset;
} completion:^(BOOL finished) {    } ];

Где я ошибаюсь?

4b9b3361

Ответ 1

Каждый раз, когда вы создаете свои собственные анимации, вам нужно передать НЕТ в качестве параметра animated::

- (void)scrollToPage:(int)page
{
    UIScrollView *scrollView = contentView;
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, 
                                 scrollView.contentOffset.y);

    [UIView animateWithDuration:.5
                          delay:0
                        options:UIViewAnimationCurveEaseInOut
                     animations:^{
                         [scrollView setContentOffset:offset animated:NO];
                     } completion:nil];

    [self pageControlUpdate];
}

Ответ 2

Используя общедоступные API, я не считаю, что в настоящее время это возможно. Предполагая, что вам не нужно взаимодействие с пользователем во время анимации, вам лучше будет анимировать позицию ваших подтекстов UIScrollView (т.е. Содержимого прокрутки), а затем настроить contentOffset без анимации на завершение. Вы можете сделать это так:

- (void) scrollToPage:(int)page {
    UIScrollView *scrollView = contentView;
    scrollView.userInteractionEnabled = NO;
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y);
    CGFloat delta = offset.x - scrollView.contentOffset.x;

    __block int animationCount = 0;
    for (UIView *view in scrollView.subviews) {
        [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            animationCount++;
            CGRect frame = view.frame;
            frame.origin.x -= delta;
            view.frame = frame;
        } completion:^(BOOL finished) {
            animationCount--;
            if (animationCount == 0) {
                scrollView.contentOffset = offset;
                for (UIView *view in scrollView.subviews) {
                    CGRect frame = view.frame;
                    frame.origin.x += delta;
                    view.frame = frame;
                }
                scrollView.userInteractionEnabled = YES;
            }
        }];
    }
}

Я могу подтвердить, что это работает, как и ожидалось, я сам тестировал его.

Ответ 3

[UIView animateWithDuration:(Animation_Duration)
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                     [scroll setContentOffset:CGPointMake(PointX, PointY) animated:NO];
                      }
                     completion:^(BOOL finished){}];`

Ответ 4

Этот класс полностью спас мне жизнь:

MOScroll на GitHub.com

Он имеет

- (void)setContentOffset:(CGPoint)contentOffset withTimingFunction:(CAMediaTimingFunction *)timingFunction duration:(CFTimeInterval)duration;

Также как частный API, но со всеми общедоступными методами и математикой.