UIPinchGestureRecognizer позиционирует защемленный вид между двумя пальцами
Я успешно реализовал масштабирование масштабирования вида. Тем не менее, мнение не позиционирует себя так, как я хотел. Для stackoverflowers с iPad я хотел бы, чтобы мой взгляд был центрирован, как на iPad Photos.app: когда вы щелкаете и увеличиваете масштаб альбома, фотографии появляются в расширяющемся представлении. Этот вид приблизительно центрирован с верхним правом углом на первом пальце и нижним левым пальцем на другом пальце. Я смешал его с распознающим панорамирование, но таким образом пользователь всегда должен зажимать, а затем панорамировать для настройки.
Вот так графическое объяснение, я могу опубликовать видео моего приложения, если это неясно (не секрет, я пытаюсь воспроизвести Photos.app iPad...)
Итак, для начального положения пальцев, начинающего масштабирование:
![enter image description here]()
Это фактический "увеличенный" кадр. Квадрат больше, но положение ниже пальцев.
![given the start position]()
Вот что я хотел бы иметь: тот же размер, но разные origin.x и y:
![enter image description here]()
(извините за свои плохие навыки работы с фотошопом ^^)
Ответы
Ответ 1
Вы можете получить CGPoint
середины между двумя пальцами через следующий код в методе handlingPinchGesture
.
CGPoint point = [sender locationInView:self];
Мой метод handlePinchGesture
приведен ниже.
/*
instance variables
CGFloat lastScale;
CGPoint lastPoint;
*/
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender {
if ([sender numberOfTouches] < 2)
return;
if (sender.state == UIGestureRecognizerStateBegan) {
lastScale = 1.0;
lastPoint = [sender locationInView:self];
}
// Scale
CGFloat scale = 1.0 - (lastScale - sender.scale);
[self.layer setAffineTransform:
CGAffineTransformScale([self.layer affineTransform],
scale,
scale)];
lastScale = sender.scale;
// Translate
CGPoint point = [sender locationInView:self];
[self.layer setAffineTransform:
CGAffineTransformTranslate([self.layer affineTransform],
point.x - lastPoint.x,
point.y - lastPoint.y)];
lastPoint = [sender locationInView:self];
}
Ответ 2
Взгляните на Затрагивает образец проекта. В частности, эти методы могут помочь вам:
// scale and rotation transforms are applied relative to the layer anchor point
// this method moves a gesture recognizer view anchor point between the user fingers
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
UIView *piece = gestureRecognizer.view;
CGPoint locationInView = [gestureRecognizer locationInView:piece];
CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
piece.center = locationInSuperview;
}
}
// scale the piece by the current scale
// reset the gesture recognizer rotation to 0 after applying so the next callback is a delta from the current scale
- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer
{
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
[gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]);
[gestureRecognizer setScale:1];
}
}