Я создал пользовательскую версию UIPinchGestureRecognizer, чтобы сделать именно то, что вы ищете.Он использует наклон линии между двумя пальцами, чтобы определить направление шкалы.Это делает 3 типа: вертикальный;Горизонтальный;и комбинированный (диагональ).Пожалуйста, смотрите мои заметки внизу.
-(void) scaleTheView:(UIPinchGestureRecognizer *)pinchRecognizer
{
if ([pinchRecognizer state] == UIGestureRecognizerStateBegan || [pinchRecognizer state] == UIGestureRecognizerStateChanged) {
if ([pinchRecognizer numberOfTouches] > 1) {
UIView *theView = [pinchRecognizer view];
CGPoint locationOne = [pinchRecognizer locationOfTouch:0 inView:theView];
CGPoint locationTwo = [pinchRecognizer locationOfTouch:1 inView:theView];
NSLog(@"touch ONE = %f, %f", locationOne.x, locationOne.y);
NSLog(@"touch TWO = %f, %f", locationTwo.x, locationTwo.y);
[scalableView setBackgroundColor:[UIColor redColor]];
if (locationOne.x == locationTwo.x) {
// perfect vertical line
// not likely, but to avoid dividing by 0 in the slope equation
theSlope = 1000.0;
}else if (locationOne.y == locationTwo.y) {
// perfect horz line
// not likely, but to avoid any problems in the slope equation
theSlope = 0.0;
}else {
theSlope = (locationTwo.y - locationOne.y)/(locationTwo.x - locationOne.x);
}
double abSlope = ABS(theSlope);
if (abSlope < 0.5) {
// Horizontal pinch - scale in the X
[arrows setImage:[UIImage imageNamed:@"HorzArrows.png"]];
arrows.hidden = FALSE;
// tranform.a = X-axis
NSLog(@"transform.A = %f", scalableView.transform.a);
// tranform.d = Y-axis
NSLog(@"transform.D = %f", scalableView.transform.d);
// if hit scale limit along X-axis then stop scale and show Blocked image
if (((pinchRecognizer.scale > 1.0) && (scalableView.transform.a >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.a <= 0.1))) {
blocked.hidden = FALSE;
arrows.hidden = TRUE;
} else {
// scale along X-axis
scalableView.transform = CGAffineTransformScale(scalableView.transform, pinchRecognizer.scale, 1.0);
pinchRecognizer.scale = 1.0;
blocked.hidden = TRUE;
arrows.hidden = FALSE;
}
}else if (abSlope > 1.7) {
// Vertical pinch - scale in the Y
[arrows setImage:[UIImage imageNamed:@"VerticalArrows.png"]];
arrows.hidden = FALSE;
NSLog(@"transform.A = %f", scalableView.transform.a);
NSLog(@"transform.D = %f", scalableView.transform.d);
// if hit scale limit along Y-axis then don't scale and show Blocked image
if (((pinchRecognizer.scale > 1.0) && (scalableView.transform.d >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.d <= 0.1))) {
blocked.hidden = FALSE;
arrows.hidden = TRUE;
} else {
// scale along Y-axis
scalableView.transform = CGAffineTransformScale(scalableView.transform, 1.0, pinchRecognizer.scale);
pinchRecognizer.scale = 1.0;
blocked.hidden = TRUE;
arrows.hidden = FALSE;
}
} else {
// Diagonal pinch - scale in both directions
[arrows setImage:[UIImage imageNamed:@"CrossArrows.png"]];
blocked.hidden = TRUE;
arrows.hidden = FALSE;
NSLog(@"transform.A = %f", scalableView.transform.a);
NSLog(@"transform.D = %f", scalableView.transform.d);
// if we have hit any limit don't allow scaling
if ((((pinchRecognizer.scale > 1.0) && (scalableView.transform.a >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.a <= 0.1))) || (((pinchRecognizer.scale > 1.0) && (scalableView.transform.d >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.d <= 0.1)))) {
blocked.hidden = FALSE;
arrows.hidden = TRUE;
} else {
// scale in both directions
scalableView.transform = CGAffineTransformScale(scalableView.transform, pinchRecognizer.scale, pinchRecognizer.scale);
pinchRecognizer.scale = 1.0;
blocked.hidden = TRUE;
arrows.hidden = FALSE;
}
} // else for diagonal pinch
} // if numberOfTouches
} // StateBegan if
if ([pinchRecognizer state] == UIGestureRecognizerStateEnded || [pinchRecognizer state] == UIGestureRecognizerStateCancelled) {
NSLog(@"StateEnded StateCancelled");
[scalableView setBackgroundColor:[UIColor whiteColor]];
arrows.hidden = TRUE;
blocked.hidden = TRUE;
}
}
Не забудьте добавить протокол в заголовочный файл контроллера представления:
@interface WhiteViewController : UIViewController <UIGestureRecognizerDelegate>
{
IBOutlet UIView *scalableView;
IBOutlet UIView *mainView;
IBOutlet UIImageView *arrows;
IBOutlet UIImageView *blocked;
}
@property (strong, nonatomic) IBOutlet UIView *scalableView;
@property (strong, nonatomic) IBOutlet UIView *mainView;
@property (strong, nonatomic)IBOutlet UIImageView *arrows;
@property (strong, nonatomic)IBOutlet UIImageView *blocked;
-(void) scaleTheView:(UIPinchGestureRecognizer *)pinchRecognizer;
@end
И добавить распознаватель в viewDidLoad:
- (void)viewDidLoad
{ UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scaleTheView:)];
[pinchGesture setDelegate:self];
[mainView addGestureRecognizer:pinchGesture];
arrows.hidden = TRUE;
blocked.hidden = TRUE;
[scalableView setBackgroundColor:[UIColor whiteColor]];}
Это настроено на использование основного вида для захвата пинча;и манипулировать вторым видом.Таким образом, вы все еще можете масштабировать его, так как вид становится маленькимВы можете изменить его, чтобы реагировать непосредственно на масштабируемое представление.
LIMITS: Я произвольно выбрал начальный размер моего обзора, чтобы ограничение масштаба 2,0 равнялось полноэкранному.Моя нижняя шкала установлена на 0,1.
ВЗАИМОДЕЙСТВИЕ ПОЛЬЗОВАТЕЛЯ: Я возиться со многими вещами взаимодействия с пользователем, такими как изменение цвета фона представления и добавление / изменение стрелок над видом, чтобы показать направление.Важно дать им обратную связь во время процесса масштабирования, особенно когда изменение направления, как позволяет этот код.
BUG: в UIPinchGestureRecognizer от Apple есть ошибка.Он регистрирует UIGestureRecognizerStateBegan одним касанием пальца, как и следовало ожидать.Но как только он находится в StateBegan или StateChanged, вы можете поднять один палец, и состояние останется.Он не перемещается в StateEnded или StateCancelled, пока оба пальца не будут подняты.Это создало ошибку в моем коде и много головной боли!If numberOfTouches> 1 исправляет это.
БУДУЩЕЕ: Вы можете изменить настройки наклона для масштабирования только в одном направлении или только 2. Если вы добавите изображения стрелок, вы сможете увидеть, как они меняются при повороте пальцев.