Как я могу отменить отскок масштабирования UIScrollView?

Я использую масштабирующий UIScrollView, чтобы показывать изображения в моем приложении для iPad. Масштабирование работает отлично, с помощью щепотки увеличения или уменьшения изображения в зависимости от обстоятельств. У меня также включен bouncesZoom, поэтому он возвращается к минимальному или максимальному масштабированию, если пользователь слишком сильно растягивает его в ту или иную сторону.

Теперь я хотел бы распознать, когда сжатие закончилось, когда изображение на 10% меньше минимального размера увеличения, и в таком случае предотвратить отскок и запустить другую анимацию, которая сжимает изображение, чтобы «закрыть» его. Таким образом, может быть что-то вроде жеста «ущипнуть, чтобы закрыть». В простейшем случае я придумал следующее:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    if (self.zoomBouncing && zoomedToScale / self.minimumZoomScale < 0.90) {
        // We've let go and were under 90% of the minimum size.
        self.minimumZoomScale = zoomedToScale;
        [self shrinkImageToNothing];
    } else {
        // How far have we gone?
        zoomedToScale = self.zoomScale;
    }
}

Это отлично работает, за исключением того, что в этот момент он уже подпрыгивает, поэтому установка minimumZoomScale ничего не делает. Следовательно, отскок и сжатие происходят одновременно, что, как вы могли догадаться, выглядит довольно странно.

Итак, мой вопрос: как я могу предотвратить отскок только в этой конкретной ситуации? Не существует метода UIScrollViewDelegate, который позволяет моему коду делать что-то между окончанием жеста и тем, когда UIScrollView решает вернуться в норму. Я безуспешно пробовал кучу других техник, в том числе:

  • Возвращение nil из –viewForZoomingInScrollView:, когда мой порог масштабирования 90% был пройден. Не работает, потому что этот метод вызывается в начале жеста, а не для каждой точки масштабирования.
  • Установка bouncesZoom в -scrollViewDidZoom: на false, если коэффициент масштабирования меньше 90%, и на true, если он больше или равен 90%. Из-за того, что изображение сильно дрожит, когда масштаб опускается ниже 90%, он запрещает этот размер, когда bouncesZoom имеет значение false.
  • Добавление метода -touchesEnded:withEvent. Его никогда не называют.
  • Добавление моего собственного UIPinchGestureRecognizer для одновременного выполнения с собственным распознавателем щипков UIScrollView. Не работает, потому что его обработчики (и методы делегата) вызываются после щипкового жеста UIScrollView, который принимает решение отскочить до того, как мой жест может сказать это тоже. Я попытался удалить все основные жесты, добавить свои и вернуть основные жесты. Но мой жест был все еще вызван после того, как UIScrollView решил, что он подпрыгивает.

Так что я немного растерялся. Кто-нибудь еще пробовал сделать что-то подобное?


person theory    schedule 07.03.2011    source источник


Ответы (3)


Вам нужно просто установить для этого свойства значение NO. (например, в ViewDidLoad)

scrollView.bouncesZoom = НЕТ;

person torutoru    schedule 29.07.2013

Думаю, написание этого вопроса помогло мне встать на путь поиска решения. И, к счастью, это довольно просто! Итак, первый шаг, в моем коде, который устанавливает minimumZoomScale, я также установил cachedMinZoomScale ivar на то же значение. При этом добиться того, чтобы отскок не происходил, когда масштаб меньше 90% от минимума, на самом деле довольно просто:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    if (self.zoomScale / cachedMinZoomScale < 0.90) {
        self.minimumZoomScale = self.zoomScale;
    } else {
        self.minimumZoomScale = cachedMinZoomScale;
    }
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
    if (self.zoomScale / cachedMinZoomScale < 0.90) {
        [self shrinkImageToNothing];
    }
}

Как правило, при увеличении масштаба прокрутки оставьте -self.minimumZoomScale на текущем масштабе масштабирования, если он меньше 90% от фактического минимума, но установите его на этот фактический минимум при любом другом масштабе масштабирования. Затем, когда масштабирование завершится, если мы ниже этого порога 90%, он не будет ни к чему возвращаться, потому что это уже будет минимальный размер, а затем просто вызовите новую анимацию, чтобы сжать, чтобы закрыть.

Простой. Фух!

person theory    schedule 07.03.2011
comment
Что делает shrinkImageToNothing и где устанавливается cachedMinZoomScale? - person jjxtra; 09.05.2012

Попробуйте это, [imageScrollview setBounces: NO];

person Kumaresan P    schedule 25.07.2012
comment
Я включил это по другим причинам, как описано в вопросе. Принятый ответ касается моей потребности. - person theory; 01.08.2012