2013-04-06 68 views
3

如果有人遇到iOS的谷歌地图应用程序有一个很好的功能,用一个手指放大/缩小: 在uiscrollview上双击,然后立即向上滑动手指或向下放大/缩小。 有谁知道这是如何实现的?谷歌发布的任何片段?Doubletap和滑动/拖动手指放大/缩小

+0

没有人碰到过吗? – 2013-04-07 09:27:06

+0

这似乎没有人))伟大的机会成为第一! – faviomob 2013-06-18 06:36:59

+0

是的,真是一种快乐...... – 2013-06-22 22:45:23

回答

3

我将此功能添加到my UIScrollView category
实际的轻拍识别很容易,计算“正确”(无论什么感觉“正确”)zoomScale是问题...如果您认为该类别不够好处理,请不要犹豫,告诉我,并打开github页面上的新问题。

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); 
     } 
    } 
} 
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) 
    } 
} 

这并不表明在滚动视图,这是一堆额外的代码在实际设置zoomScale - 你想要得到的移动手势的位置和中心放大一下。您还需要限制zoomScale,并且也可以处理缩放结束。