Кажется, это лучший ресурс для ответа на этот вопрос в Интернете. Еще одно близкое решение можно найти здесь.
Я решил эту проблему весьма удовлетворительным образом другим способом, по сути, заменив в уравнении мой собственный распознаватель жестов. Я настоятельно рекомендую всем, кто пытается достичь эффекта, запрошенного исходным плакатом, рассмотреть эту альтернативу по сравнению с агрессивным подклассом UIScrollView.
Следующий процесс обеспечит:
UIScrollView, содержащий ваше собственное представление
Масштабирование и панорамирование двумя пальцами (через UIPinchGestureRecognizer)
Обработка событий вашего представления для всех остальных касаний
Во-первых, предположим, что у вас есть контроллер представления и его представление. В IB сделайте представление подчиненным представлением scrollView и настройте правила изменения размера представления, чтобы его размер не изменялся. В атрибутах scrollview включите все, что написано «bounce», и выключите off «delaysContentTouches». Также вы должны установить минимальное и максимальное масштабирование, отличное от значения по умолчанию 1.0, поскольку, как говорится в документации Apple, это требуется для работы масштабирования.
Создайте собственный подкласс UIScrollView и сделайте этот scrollview этим настраиваемым подклассом. Добавьте выход к вашему контроллеру представления для просмотра прокрутки и подключите их. Теперь вы полностью настроены.
Вам нужно будет добавить следующий код в подкласс UIScrollView, чтобы он прозрачно передавал события касания (я подозреваю, что это можно было бы сделать более элегантно, возможно, даже полностью обойдя подкласс):
#pragma mark -
#pragma mark Event Passing
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesEnded:touches withEvent:event];
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
return NO;
}
Добавьте этот код в свой контроллер представления:
- (void)setupGestures {
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];
[self.view addGestureRecognizer:pinchGesture];
[pinchGesture release];
}
- (IBAction)handlePinchGesture:(UIPinchGestureRecognizer *)sender {
if ( sender.state == UIGestureRecognizerStateBegan ) {
//Hold values
previousLocation = [sender locationInView:self.view];
previousOffset = self.scrollView.contentOffset;
previousScale = self.scrollView.zoomScale;
} else if ( sender.state == UIGestureRecognizerStateChanged ) {
//Zoom
[self.scrollView setZoomScale:previousScale*sender.scale animated:NO];
//Move
location = [sender locationInView:self.view];
CGPoint offset = CGPointMake(previousOffset.x+(previousLocation.x-location.x), previousOffset.y+(previousLocation.y-location.y));
[self.scrollView setContentOffset:offset animated:NO];
} else {
if ( previousScale*sender.scale < 1.15 && previousScale*sender.scale > .85 )
[self.scrollView setZoomScale:1.0 animated:YES];
}
}
Обратите внимание, что в этом методе есть ссылки на ряд свойств, которые вы должны определить в файлах классов вашего контроллера представления:
CGFloat previousScale;
CGPoint previousOffset;
CGPoint previousLocation;
CGPoint location;
Хорошо, вот и все!
К сожалению, мне не удалось заставить scrollView отображать свои скроллеры во время жеста. Я испробовал все эти стратегии:
//Scroll indicators
self.scrollView.showsVerticalScrollIndicator = YES;
self.scrollView.showsVerticalScrollIndicator = YES;
[self.scrollView flashScrollIndicators];
[self.scrollView setNeedsDisplay];
Одна вещь, которая мне действительно понравилась, - если вы посмотрите на последнюю строку, вы заметите, что она захватывает любое окончательное масштабирование, составляющее около 100%, и просто округляет его до этого. Вы можете отрегулировать свой уровень толерантности; Я видел это в поведении масштабирования Pages и подумал, что это было бы неплохо.
person
SG1
schedule
25.05.2010