Резюме: иногда UIScrollView
вносит нежелательные изменения в значение contentOffset
, в результате чего приложение отображает неправильное место в просматриваемом документе. Нежелательное изменение происходит в сочетании с анимированным изменением zoomScale
представления прокрутки.
Подробности. У меня возникают проблемы при уменьшении масштаба с помощью CATiledLayer
в UIScrollView
. CATiledLayer
содержит PDF-файл, и когда contentOffset
находится в определенном диапазоне, когда я уменьшаю масштаб, contentOffset
изменяется (это ошибка) до того, как происходит масштабирование. Кажется, что contentOffset
изменено в коде Apple.
Чтобы проиллюстрировать проблему, я изменил пример приложения Apple, ZoomingPDFViewer. Код находится на github: https://github.com/DirkMaas/ZoomingPDFViewer-bug
Нажатие приведет к изменению zoomScale
на 0,5 с помощью animateWithDuration
, что приведет к уменьшению масштаба. Если contentOffset.y
UIScrollView
меньше 2700 или больше 5900, анимация zoomScale
работает нормально. Если касание происходит, когда contentOffset.y
находится между этими двумя значениями, contentOffset.y
перепрыгнет (не анимируется) примерно до 2700, а затем произойдет zoomScale
анимация, но в то же время будет происходить прокрутка, так что, когда анимация будет выполнена, contentOffset.y
там, где должно быть. Но откуда скачок?
Например, скажем, contentOffset.y
равно 2000 при касании экрана: анимация zoomScale
работает просто отлично; contentOffset.y
не изменяется.
Но если contentOffset.y
равно 4000 при нажатии на экран: contentOffset.y
подскочит без анимации примерно до 2700, а затем масштабирование и прокрутка начнутся с этой точки и будут происходить одновременно. Когда анимация завершена, кажется, что мы увеличили масштаб прямо с 4000, поэтому мы оказываемся в нужном месте, но поведение неправильное.
Примечание по пользовательскому интерфейсу:
- текст можно прокручивать по вертикали обычным способом
- текст можно увеличивать и уменьшать, сжимая обычным способом
- одно касание приведет к тому, что
zoomScale
будет установлено на 0,5; изменение анимировано
Я заметил, что если zoomScale
больше 0,5, скачок не такой большой. Кроме того, если я использую setZoomScale:animated:
вместо animateWithDuration
, ошибка исчезает, но я не могу использовать ее, потому что мне нужно цепочку анимаций.
Вот краткое изложение того, что я сделал (код в github включает эти изменения):
- Загружен ZoomingPDFViewer с http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html и открыл его в XCode.
- Изменены настройки сборки | Архитектуры | Базовый SDK для последней версии iOS (iOS 4.3) изменил настройки сборки | GCC 4.2 - Язык | Скомпилируйте исходники в соответствии с Objective-C++
- удален TestPage.pdf из проекта
- добавил в проект "whoiam 5 24 cropped 3-2.pdf" на свое место
- добавлен
PDFScrollView *scrollView;
вZoomingPDFViewerViewController
класс - изменил
loadView
вZoomingPDFViewerViewController
для инициализацииscrollView
вместоsv
- добавлены
viewDidLoad
,handleTapFrom:recognizer
иzoomOut
кZoomingPDFViewerViewController
в PDFScrollview.m - закомментированы
scrollViewDidEndZooming:withView:atScale
иscrollViewWillBeginZooming:withView:
, потому что они отвлекают внимание от обсуждаемой проблемы на фоне изображения.
Большое спасибо за то, что терпите меня, и за любую помощь!
scrollViewDidEndZooming:withView:atScale
для уведомления о завершении масштабирования? - person Michael Frederick   schedule 14.09.2011animateWithDuration:
вместоsetZoomScale:Animated:
, потому что, если я что-то не упустил, последний не позволяет контролировать продолжительность, и потому что блочные анимации, на мой взгляд, лучше справляются с сохранением связанного кода. вместе. Кроме того, Apple, похоже, поощряет использование блочной анимации. Так что, возможно, мне следовало сказать, что я не хочу использоватьsetZoomScale:Animated:
. Спасибо за комментарий! - person DirkMaas   schedule 14.09.2011