【问题标题】:Doubletap and slide/drag finger to zoom in/out双击并滑动/拖动手指以放大/缩小
【发布时间】:2013-03-28 18:03:03
【问题描述】:

如果有人遇到过适用于 iOS 的谷歌地图应用程序,这里有个很棒的功能可以用一根手指放大/缩小: 双击 uiscrollview,然后立即向上或向下滑动手指以放大/缩小。 有谁知道这是如何实现的?谷歌有没有发布任何sn-p?

【问题讨论】:

  • 没有人发现这个???
  • 似乎没有人 )) 成为第一名的好机会!

标签: iphone sdk uiscrollview zooming


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    使用 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,这是一堆额外的代码 - 您需要获取平移手势的位置并围绕该位置进行缩放。您还需要钳制缩放比例,并且可能还要处理缩放结束。

    【讨论】:

      【解决方案3】:

      此示例使用 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 存储您的初始缩放比例,以便我们恢复它。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-27
        • 1970-01-01
        • 1970-01-01
        • 2014-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-04
        相关资源
        最近更新 更多