Проблема с uiscrollview setcontentoffset animated не прокручивается при анимации: установлено yes - PullRequest
42 голосов
/ 15 октября 2010

Это очень странно, и мне интересно, есть ли у кого-нибудь мысли?

Я пытаюсь прокрутить UIScrollView в ответ на нажатие кнопки на iPad.

Если я это сделаю:

CGPoint currentOff = scrollView.contentOffset;
currentOff.x+=240;
[scrollView setContentOffset:currentOff animated: NO];

Вид прокрутки переходит в требуемое положение, как и ожидалось, но я хочу, чтобы он прокручивался. Тем не менее, когда я делаю:

CGPoint currentOff = scrollView.contentOffset;
currentOff.x+=240;
[scrollView setContentOffset:currentOff animated: YES];

Тогда это ничего не делает! У меня есть другой вид прокрутки, который работает правильно и отвечает на setContentOffset:YES, как и ожидалось, поэтому я довольно озадачен. Любые идеи о том, почему прокрутка может не произойти, приветствуются!

Кроме того, - (void)scrollViewDidScroll:(UIScrollView *)sender вообще ничего не получает, когда используется animated:YES, но вызывается, когда используется animated:NO!

Ответы [ 9 ]

79 голосов
/ 09 марта 2012

У меня тоже было такое, и я решил обойти это:

[UIView animateWithDuration:.25 animations:^{
    self.scrollView.contentOffset = ...;
}];
7 голосов
/ 03 июня 2013

Исходя из личного опыта, эта проблема возникает, когда setContentOffset: вызывается несколько раз, прежде чем анимация успела запуститься.

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

setContentOffset: вызывается animated, который устанавливает новое значение смещения.setContentOffset: впоследствии вызывается с теми же параметрами, что отменяет анимацию.Он также отмечает, что новые параметры совпадают со старыми параметрами, поэтому предполагается, что ничего не нужно делать, даже если анимация еще не запущена.

Приведенное выше решение каким-то образом нарушает этот цикл, но, возможно, менееРешение kludgy заключается в установке точек останова в коде и устранении нескольких вызовов.

2 голосов
/ 16 июня 2011

Трудно сказать с тем фрагментом кода, который вы дали. И на самом деле, если вы говорите, что у вас есть проект, где все работает в одинаковых условиях, то, очевидно, условия не совпадают :) Я не смог воспроизвести проблему, но вот некоторые предположения для 2 случая:

  1. Создание UIScrollView с пером.

    • Только не забудьте создать IBOutlet и привязать его к элементу scrollView в nib. В простом приложении, основанном на представлении, сразу после этого я получил scrollView, работающий в анимированном виде: как ДА, так и НЕТ. Но чтобы сделать работу

    -(void)scrollViewDidScroll:(UIScrollView *)sender; Вы должны установить делегата:

yourScrollView.delegate = self;

где 'self' - это класс, где у вас есть функция scrollViewDidScroll; Кстати, этот класс должен соответствовать протоколу UIScrollViewDelegate.

2.Создание объекта UIScrollView вручную.

  • здесь идея в основном та же самая, поэтому я просто предоставлю простой код:

    -(void) creatingScrollView {
        UIScrollView *newScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 5, 280, 44)];
        newScroll.pagingEnabled = YES;
        newScroll.showsVerticalScrollIndicator = NO;
        newScroll.showsHorizontalScrollIndicator = NO;
    
        // ... some subviews being added to our scroll view
    
        newScroll.delegate = self;
        [self.view addSubview:newScroll];
        [newScroll release];
    }
    

Это работает для меня. Надеюсь, что это полезно.

1 голос
/ 14 июля 2018

Я работаю с табличными представлениями, поскольку решения aepryus говорит: setContentOffset: вызывается одновременно с другими анимациями .

В моем случае я просто инвертировал следующие команды:

[tableView reloadData];
[tableView setContentOffset:CGPointMake(240, 0) animated:FALSE];

как это

[tableView setContentOffset:CGPointMake(240, 0) animated:FALSE];
[tableView reloadData];

Анимация запускается после успешного изменения смещения контента.

1 голос
/ 02 апреля 2015

Решение для Xamarin.iOS

InvokeOnMainThread(() =>
{
  scrollView.SetContentOffset(new PointF((page * UIScreen.MainScreen.Bounds.Width), 0), true);
});

Это также можно решить с помощью UIView.Animate

UIView.Animate(
    duration: .25,
    animation: () =>
    {
       scrollView.SetContentOffset(new PointF((value * UIScreen.MainScreen.Bounds.Width), 0), true);
    }
);
0 голосов
/ 30 мая 2016
func scrollViewDidScroll(scrollView: UIScrollView) {

    dispatch_async(dispatch_get_main_queue(),{

        UIView.animateWithDuration(0.10, animations: { () -> Void in

            let loginScrollViewCurrentPosition:CGPoint = CGPointMake(self.loginScrollView.contentOffset.x, self.loginScrollView.contentOffset.y) as CGPoint
            self.loginScrollView.setContentOffset(loginScrollViewCurrentPosition, animated: true)

            })
    })

}
0 голосов
/ 06 августа 2014

У меня была такая же проблема, в моем случае я также перехватывал:

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {...}

Этот метод вызывается сразу после: (Не дожидается окончания анимации):

[scrollView setContentOffset:currentOff animated: YES];

Это означает, что если у вас есть какая-либо логика, которая «ждет» конца анимации и вы перехватываете scrollViewDidEndScrollingAnimation, тогда результат будет неопределенным, т.е.

РЕДАКТИРОВАТЬ: принятое решение / обходной путь:

[UIView animateWithDuration:.25 animations:^{
    self.scrollView.contentOffset = ...;
}];

Также «работает» в моем сценарии, потому что установка contentOffset напрямую не вызывает scrollViewDidEndScrollingAnimation

0 голосов
/ 26 мая 2014

Я столкнулся с той же проблемой, что ScrollView не прокручивает. И я отключил «Использовать автоматическую компоновку» в представлении, а затем ScrollView работает.

0 голосов
/ 08 марта 2011

Вы можете попробовать:

[scrollView setContentOffset:CGPointMake(240, 0) animated:YES];
...