这似乎是互联网上这个问题的最佳资源。可以在这里找到另一个接近的解决方案。
我以不同的方式以非常令人满意的方式解决了这个问题,主要是通过将我自己的手势识别器替换为等式。我强烈建议任何试图达到原始海报要求的效果的人考虑这种替代方法,而不是激进的UIScrollView
.
以下过程将提供:
首先,假设您有一个视图控制器及其视图。在 IB 中,使视图成为 scrollView 的子视图并调整视图的调整大小规则,使其不会调整大小。在滚动视图的属性中,打开任何“反弹”并关闭“ delaysContentTouches
”。此外,您必须将缩放最小值和最大值设置为默认值 1.0 以外的值,因为正如 Apple 的文档所说,这是缩放工作所必需的。
创建 的自定义子类UIScrollView
,并使此滚动视图成为自定义子类。为滚动视图添加一个出口到您的视图控制器并将它们连接起来。你现在已经完全配置好了。
您需要将以下代码添加到UIScrollView
子类中,以便它透明地传递触摸事件(我怀疑这可以更优雅地完成,甚至可能完全绕过子类):
#pragma mark -
#pragma mark Event Passing
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesEnded:touches withEvent:event];
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
return NO;
}
将此代码添加到您的视图控制器:
- (void)setupGestures {
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];
[self.view addGestureRecognizer:pinchGesture];
[pinchGesture release];
}
- (IBAction)handlePinchGesture:(UIPinchGestureRecognizer *)sender {
if ( sender.state == UIGestureRecognizerStateBegan ) {
//Hold values
previousLocation = [sender locationInView:self.view];
previousOffset = self.scrollView.contentOffset;
previousScale = self.scrollView.zoomScale;
} else if ( sender.state == UIGestureRecognizerStateChanged ) {
//Zoom
[self.scrollView setZoomScale:previousScale*sender.scale animated:NO];
//Move
location = [sender locationInView:self.view];
CGPoint offset = CGPointMake(previousOffset.x+(previousLocation.x-location.x), previousOffset.y+(previousLocation.y-location.y));
[self.scrollView setContentOffset:offset animated:NO];
} else {
if ( previousScale*sender.scale < 1.15 && previousScale*sender.scale > .85 )
[self.scrollView setZoomScale:1.0 animated:YES];
}
}
请注意,在此方法中,您必须在视图控制器的类文件中定义许多属性:
CGFloat previousScale;
CGPoint previousOffset;
CGPoint previousLocation;
CGPoint location;
好的,就是这样!
不幸的是,我无法让 scrollView 在手势期间显示其滚动条。我尝试了所有这些策略:
//Scroll indicators
self.scrollView.showsVerticalScrollIndicator = YES;
self.scrollView.showsVerticalScrollIndicator = YES;
[self.scrollView flashScrollIndicators];
[self.scrollView setNeedsDisplay];
我真正喜欢的一件事是,如果您查看最后一行,您会注意到它会抓取大约 100% 的任何最终缩放并将其四舍五入。你可以调整你的容忍度;我在 Pages 的缩放行为中看到了这一点,并认为这将是一个不错的选择。