Limiting CGAffineTransform Scale
I am transforming a view with CGAffineTransformMake. It rotates, scales and translates. This works just fine. But I cannot figure out a way to limit the scale to a maximum size.
If the scale is exceeded, I need to still apply the current rotation and translation.
Any suggestions are greatly appreciated!
Source:
UITouch *touch1 = [sortedTouches objectAtIndex:0];
UITouch *touch2 = [sortedTouches objectAtIndex:1];
CGPoint beginPoint1 = *(CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch1);
CGPoint currentPoint1 = [touch1 locationInView:self.superview];
CGPoint beginPoint2 = *(CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch2);
CGPoint currentPoint2 = [touch2 locationInView:self.superview];
double layerX = self.center.x;
double layerY = self.center.y;
double x1 = beginPoint1.x - layerX;
double y1 = beginPoint1.y - layerY;
double x2 = beginPoint2.x - layerX;
double y2 = beginPoint2.y - layerY;
double x3 = currentPoint1.x - layerX;
double y3 = currentPoint1.y - layerY;
double x4 = currentPoint2.x - layerX;
double y4 = currentPoint2.y - layerY;
// Solve the system:
// [a b t1, -b a t2, 0 0 1] * [x1, y1, 1] = [x3, y3, 1]
// [a b t1, -b a t2, 0 0 1] * [x2, y2, 1] = [x4, y4, 1]
double D = (y1-y2)*(y1-y2) + (x1-x2)*(x1-x2);
if (D < 0.1) {
return CGAffineTransformMakeTranslation(x3-x1, y3-y1);
}
double a = (y1-y2)*(y3-y4) + (x1-x2)*(x3-x4);
double b = (y1-y2)*(x3-x4) - (x1-x2)*(y3-y4);
double tx = (y1*x2 - x1*y2)*(y4-y3) - (x1*x2 + y1*y2)*(x3+x4) + x3*(y2*y2 + x2*x2) + x4*(y1*y1 + x1*x1);
double ty = (x1*x2 + y1*y2)*(-y4-y3) + (y1*x2 - x1*y2)*(x3-x4) + y3*(y2*y2 + x2*x2) + y4*(y1*y1 + x1*x1);
return CGAffineTransformMake(a/D, -b/开发者_运维问答D, b/D, a/D, tx/D, ty/D);
Do something like this:
CGAffineTransform transform = self.view.transform;
float scale = sqrt(transform.a*transform.a + transform.c*transform.c);
if (scale > SCALE_MAX)
self.view.transform = CGAffineTransformScale(transform, SCALE_MAX/scale, SCALE_MAX/scale);
else if (scale < SCALE_MIN)
self.view.transform = CGAffineTransformScale(transform, SCALE_MIN/scale, SCALE_MIN/scale);
At the end of your touchesMoved:withEvent: and updateOriginalTransformForTouches methods. Basically, you check if the current scale exceeds a certain SCALE_MAX value, then multiply your transformation matrix with the reversed scale value.
In case anyone needs @Enzo Tran's answer in Swift with UIPanGestureRecognizer:
func handlePinch(recognizer : UIPinchGestureRecognizer) {
if let view = recognizer.view {
view.transform = CGAffineTransformScale(view.transform,
recognizer.scale, recognizer.scale)
let transform = view.transform
let maxScale: CGFloat = 1.7 //Anything
let minScale: CGFloat = 0.5 //Anything
let scale = sqrt(transform.a * transform.a + transform.c * transform.c)
if scale > maxScale {
view.transform = CGAffineTransformScale(transform, maxScale / scale, maxScale / scale)
}
else if scale < minScale {
view.transform = CGAffineTransformScale(transform, minScale / scale, minScale / scale)
}
recognizer.scale = 1
}
}
精彩评论