Как вызвать scrollViewDidScroll: так же, как это делает UIScrollView, но во время пользовательской анимации?

У меня есть очень большой UIScrollView с горизонтальной прокруткой, который повторно использует свои подпредставления (перемещает и обновляет их, когда они находятся вне видимой области, аналогично тому, как UITableView повторно использует ячейки). Это зависит от вызова scrollViewDidScroll: делегата, который дает мне фактический contentOffset, и здесь я решаю, когда повторно использовать конкретное подпредставление. Все идет нормально.

Иногда мне нужно изменить contentOffset программно, но с пользовательской анимацией (инерция и возврат к конечной позиции). Я могу сделать это довольно легко, используя базовую анимацию.

Проблема в том, что во время пользовательской анимации метод scrollViewDidScroll: делегата не вызывается -> я должен сделать это вручную, чтобы работало повторное использование подвидов. Я пытался вызвать его с таймером, срабатывающим каждые 0,02 секунды. Теперь есть две проблемы:

  1. Я должен получить UIScrollView contentOffset, используя границы [[_scrollView.layer PresentationLayer]].origin.x, потому что во время анимации обычный _scrollView.contentOffset не меняется.

    Однако информации из PresentationLayer недостаточно для точной синхронизации - иногда она немного запаздывает.

  2. проблема заключается в том, что новый contentOffset находится далеко от текущей позиции. Похоже, встроенная анимация UIScrollView — это CAKeyframeAnimation, а scrollViewDidScroll должен вызываться на позициях ключевых кадров. Но я не могу получить их.

    Если я полагаюсь на таймер, который несинхронизируется с ключевыми кадрами, представления повторно используются в неправильных местах, и я вообще не вижу их во время анимации.

Кто-нибудь может пролить свет на то, как и когда именно UIScrollView вызывает scrollViewDidScroll во время setContentOffset:Xanimated:YES? Можно ли воспроизвести его, не нарушая правил магазина приложений?

6
задан Vilém Kurz 18 April 2012 в 12:57
поделиться