I've created a UIGestureRecognizer
much like this one:
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
This works as expected, however my client wants it to be less sensitive to touch. How can I reduce the velocity of the pinching (both inward and outward) so that it zooms at about 80% the default velocity?
Did you tried to scale
the current value to the 80%.
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat maxScale = 2.0;
CGFloat currentScale = [gestureRecognizer scale];
currentScale = 0.8 * currentScale; //80% of scaling
if(currentScale < 0.8)
currentScale = 0.8;
if(currentScale > maxScale)
currentScale = maxScale;
[gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], currentScale, currentScale);
}
Try this.
- (void)handlePinching:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
if (CGRectIsEmpty(self.initalFrame)) {
self.initalFrame = gestureRecognizer.view.frame;
// store view's original frame and never change it
}
if (self.preScale == 0.f) {
self.preScale = 1.f;
}
gestureRecognizer.scale = self.preScale;
// gestureRecognizer and view should share the same scale state at the beginning
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = gestureRecognizer.scale;
newScale = (newScale - self.preScale) * 0.8 + self.preScale;
newScale = MIN(newScale, kMaxScale);
newScale = MAX(newScale, kMinScale);
CGRect newFrame = self.initalFrame;
newFrame.size.height *= newScale;
newFrame.size.width *= newScale;
gestureRecognizer.view.frame = newFrame;
self.preScale = newScale;
}
}
The points are
- use frame to implement scale.
- do change to the scale variable's change to slow/speed scaling.
Turns out the excessive speed of the zoom was actually a bug in the linked answer's code. Sadly this doesn't actually answer my actual question though (for which I'd still like an answer!), but it does serve to solve my client's problem.
Note the added line at the bottom that resets the gestureRecognizer back to 1:
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer {
...
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
gestureRecognizer.scale = 1;
// ^ added this line
}
}
来源:https://stackoverflow.com/questions/22191582/how-to-reduce-velocity-of-pinch-zoom-uigesturerecognizer