如果有人遇到适用于iOS的Google地图应用,可以用一根手指放大/缩小: 在uiscrollview上双击,然后立即向上或向下滑动手指以放大/缩小。 有谁知道这是如何实现的?谷歌发布了任何片段吗?
答案 0 :(得分:3)
我将此功能添加到my UIScrollView category
实际的点击识别很容易,计算“正确”(无论感觉“正确”)zoomScale
是问题......如果您认为该类别处理不够好,请不要犹豫告诉我和在github页面上打开一个新问题。
答案 1 :(得分:0)
此示例使用UIScrollView的常规缩放功能,其中包含UIImageView作为子视图。例如,您可以在MWPhotoBrowser库中找到此类缩放的实现。 _imageView,_doubleTapBeganPoint,_longPressBeganPoint,_minScale是您的类(UIScrollView子类)iVars。所以从初始化开始:
UILongPressGestureRecognizer* lpgs = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(imageLongPressed:)];
lpgs.minimumPressDuration = .2;
[self addGestureRecognizer:lpgs];
标准缩放处理程序:
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return _imageView;
}
使用touchesBegan捕捉双击(UITapGestureRecognizer不希望因某种原因使用UILongPressGestureRecognizer):
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
NSUInteger tapCount = touch.tapCount;
switch (tapCount) {
case 2:
[self handleDoubleTapBegan:[touch locationInView:self.superview]];
break;
default:
break;
}
[[self nextResponder] touchesEnded:touches withEvent:event];
}
- (void)handleDoubleTapBegan:(CGPoint)touchPoint {
_doubleTapBeganPoint = touchPoint;
NSLog(@"image double tap began at location: %@", NSStringFromCGPoint(touchPoint));
}
处理长按并使用Y坐标中的差异来计算缩放比例。 _minScale存储您的初始zoomScale,以便我们可以恢复它。
- (void) imageLongPressed:(UIGestureRecognizer*)gesture {
if (gesture.state == UIGestureRecognizerStateBegan)
{
self.maximumZoomScale = _maxScale * 2;
self.minimumZoomScale = _minScale / 3;
_longPressBeganPoint = [gesture locationInView:self.superview];
[self setZoomScale:_minScale animated:YES];
NSLog(@"image long press began at location: %@", NSStringFromCGPoint(_longPressBeganPoint));
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
CGPoint p = [gesture locationInView:self.superview];
//NSLog(@"image long press changed at location: %@", NSStringFromCGPoint(p));
if (CGPointEqualToPoint(_longPressBeganPoint, _doubleTapBeganPoint))
{
_zoom = _minScale + (p.y - _longPressBeganPoint.y) / 100.0;
NSLog(@"zoom scale: %f", _zoom);
[self setZoomScale:_zoom animated:NO];
}
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
NSLog(@"image long press ended at location: %@", NSStringFromCGPoint([gesture locationInView:gesture.view]));
if (self.zoomScale < _minScale)
{
[self setZoomScale:_minScale animated:YES];
NSLog(@"min zoom scale: %f", _minScale);
}
}
}
答案 2 :(得分:0)
使用UIPanGestureRecognizer跟踪上/下拖动。 要确保仅在双击时触发,请为其指定执行以下操作的委托:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if gestureRecognizer == yourZoomRecognizer {
return touch.tapCount == 2
} else {
return true
}
}
现在处理来自手势识别器的消息。您可以像这样导出缩放比例:
let zoomFactor: CGFloat = 1.01 //Each point of pan zooms in or out by this much
var zoomScale: CGFloat = 1 //Dummy variable for example purposes.
@IBAction func handleZoomGesture(sender: UIPanGestureRecognizer) {
if sender.state == .began {
//Set initial translation to reflect the current zoomScale
let logZoom = log(zoomScale) / log(zoomFactor)
sender.setTranslation(CGPoint(x: 0, y: logZoom), in: sender.view)
} else if sender.state == .changed {
let logZoom = sender.translation(in: sender.view).y
zoomScale = pow(zoomFactor, logZoom)
}
}
这并没有显示在scrollview上实际设置zoomScale,这是一堆额外的代码 - 你需要获得平移手势的位置并围绕它放大缩放。您还需要钳制zoomScale,也可以处理缩放结束。