I'm using a UIPinchGestureRecognizer
to adjust the width (not the height) of a view in a UIScrollView
. It works with the pinch gesture's scale
property, but the contentOffset
of the scrollview doesn't change, so the view always increases on the right. This looks a bit better if I scale the contentOffset
along with the width, since then the view increases from the left-most side of the screen.
The problem is that the location of the pinch is ignored - so it always appears that a pinch is on the left side of the screen.
I need to somehow factor in the location of the pinch to the contentOffset
adjustment, so that the offset can be adjusted to keep the content at the pinch point to be in the same place.
Note: I cannot use built-in UIScrollView
pinch-zoom gesture as I only want the zoom to be one dimension, horizontal. Also, I cannot use transforms on the UIView
as I need to use the UIScrollView
.
I was pinch zooming a graph, so the pinch adjusts the width constraint on the graph view.
Here is the pinch handler:
- (void) doPinch:(UIPinchGestureRecognizer*)pinch;
{
CGFloat width = self.graphWidthConstraint.constant;
CGFloat idealWidth = 1500;
CGFloat currentScale = width / idealWidth;
CGFloat scale = currentScale - (1.0 - pinch.scale);
CGFloat minScale = 0.5;
CGFloat maxScale = 3.0;
scale = MIN(scale, maxScale);
scale = MAX(scale, minScale);
CGPoint locationScrollview = [pinch locationInView:self.graphScrollView];
CGFloat pinchXNormalized = locationScrollview.x / width;
CGPoint locationView = [pinch locationInView:self.view];
// resize
CGFloat newWidth = idealWidth * scale;
self.graphWidthConstraint.constant = newWidth;
// set offset to position point under touch
CGFloat pinchXScaled = newWidth * pinchXNormalized;
CGFloat x = pinchXScaled - locationView.x;
self.graphScrollView.contentOffset = CGPointMake(x, 0);
pinch.scale = 1;
}