【问题标题】:Max/Min Scale of Pinch Zoom in UIPinchGestureRecognizer - iPhone iOSUIPinchGestureRecognizer 中的最大/最小缩放比例 - iPhone iOS
【发布时间】:2011-03-01 04:57:42
【问题描述】:

如何将 UIPinchGestureRecognizer 的规模限制在最小和最大级别?下面的 scale 属性似乎是相对于最后一个已知的比例(与上一个状态的增量),我不知道如何为被缩放的对象的大小/高度设置限制。

-(void)scale:(id)sender {

[self.view bringSubviewToFront:[(UIPinchGestureRecognizer*)sender view]];

if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
    lastScale = 1.0;
    return;
}

CGFloat pinchscale = [(UIPinchGestureRecognizer*)sender scale];
CGFloat scale = 1.0 - (lastScale - pinchscale);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform holderTransform = holderView.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];

lastScale = [(UIPinchGestureRecognizer*)sender scale];

}

【问题讨论】:

标签: iphone ipad ios cgaffinetransform


【解决方案1】:

这是我以 Anomie 的回答为起点后想出的解决方案。

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer {

    if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
        // Reset the last scale, necessary if there are multiple objects with different scales
        lastScale = [gestureRecognizer scale];
    }

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || 
        [gestureRecognizer state] == UIGestureRecognizerStateChanged) {

        CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];

        // Constants to adjust the max/min values of zoom
        const CGFloat kMaxScale = 2.0;
        const CGFloat kMinScale = 1.0;

        CGFloat newScale = 1 -  (lastScale - [gestureRecognizer scale]); 
        newScale = MIN(newScale, kMaxScale / currentScale);   
        newScale = MAX(newScale, kMinScale / currentScale);
        CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
        [gestureRecognizer view].transform = transform;

        lastScale = [gestureRecognizer scale];  // Store the previous scale factor for the next pinch gesture call  
    }
}

【讨论】:

  • 很好的解决方案!我一直在寻找这个!为什么它不在这个问题的顶部!?谢谢
  • 在设置gestureRecognizer view的transform后添加这一行:[recognizer setScale:1.0];
  • 您好,我正在使用 ionic 最新框架 2.0.0 beta。我将在离子图像模型中打开图像全尺寸。但在最新版本的 ionic 中不支持图像滚动。所以如果你知道,请帮助我。
  • var currentScale: CGFloat = CFloat(recognizer.view!.layer(valueForKeyPath: "transform.scale"))!在这里我得到错误 >>>无法调用非函数类型'CALayer'的值
【解决方案2】:

没有办法限制UIPinchGestureRecognizer 的规模。要限制代码中的高度,您应该能够执行以下操作:

CGFloat scale = 1.0 - (lastScale - pinchscale);
CGRect bounds = [(UIPinchGestureRecognizer*)sender view].bounds;
scale = MIN(scale, maximumHeight / CGRectGetHeight(bounds));
scale = MAX(scale, minimumHeight / CGRectGetHeight(bounds));

要限制宽度,请将最后两行中的“高度”更改为“宽度”。

【讨论】:

  • 这是不正确的。如果您完全转换视图,则框架无效。比如view旋转45度,frame其实比实际的uiview大很多,所以随着你旋转,缩放因子会发生变化,然后尝试夹紧。
  • 可行,或者您可以使用比例值而不是我的回答中的特定高度/宽度值。
【解决方案3】:

我从 Paul Solt 和 Anoime 的回答中收集了一些信息,并将其添加到我为 UIViewController 制作的现有类别中,以允许使任何 UIView 可拖动,现在使用手势和变换使其可捏合。

注意:这会弄脏您正在制作的可拖动/可捏合视图的标记属性。因此,如果您需要该标签用于其他用途,您可以考虑将该值放在该技术使用的 NSMutableDictionary 中。这可以作为 [self dictForView:theView]

在您的项目中实施:

您可以使视图控制器“视图”中的任何子视图可拖动或可收缩(或两者兼有) 在 viewDidLoad 中放置一行代码(例如:)

[self makeView:mySubView draggable:YES pinchable:YES minPinchScale:0.75 maxPinchScale:1.0];

在 viewDidUnload 中关闭它(发布访客和字典):

[self makeView:mySubView draggable:NO pinchable:NO minPinchScale:1.0 maxPinchScale:1.0];

DragAndPinchScale.h 文件

#import <UIKit/UIKit.h>

@interface UIViewController (DragAndPinchScale)

-(void) makeView:(UIView*)aView 
       draggable:(BOOL)draggable 
       pinchable:(BOOL)pinchable 
   minPinchScale:(CGFloat)minPinchScale
   maxPinchScale:(CGFloat)maxPinchScale;


-(NSMutableDictionary *) dictForView:(UIView *)theView;
-(NSMutableDictionary *) dictForViewGuestures:(UIGestureRecognizer *)guesture;

@end

DragAndPinchScale.m 文件

#import "DragAndPinchScale.h"

@implementation UIViewController (DragAndPinchScale)


-(NSMutableDictionary *) dictForView:(UIView *)theView{
    NSMutableDictionary *dict = (NSMutableDictionary*) (void*) theView.tag;
    if (!dict) {
        dict = [[NSMutableDictionary dictionary ] retain];
        theView.tag = (NSInteger) (void *) dict;
    }

    return dict;

}


-(NSMutableDictionary *) dictForViewGuestures:(UIGestureRecognizer *)guesture {
    return [self dictForView:guesture.view];
}


- (IBAction)fingersDidPinchInPinchableView:(UIPinchGestureRecognizer *)fingers {
    NSMutableDictionary *dict = [self dictForViewGuestures:fingers];
    UIView *viewToZoom = fingers.view;
    CGFloat lastScale;
    if([fingers state] == UIGestureRecognizerStateBegan) {
        // Reset the last scale, necessary if there are multiple objects with different scales
        lastScale = [fingers scale];
    } else {
        lastScale = [[dict objectForKey:@"lastScale"] floatValue];
    }

    if ([fingers state] == UIGestureRecognizerStateBegan || 
        [fingers state] == UIGestureRecognizerStateChanged) {

        CGFloat currentScale = [[[fingers view].layer valueForKeyPath:@"transform.scale"] floatValue];

        // limits to adjust the max/min values of zoom
        CGFloat maxScale = [[dict objectForKey:@"maxScale"] floatValue];
        CGFloat minScale = [[dict objectForKey:@"minScale"] floatValue];

        CGFloat newScale = 1 -  (lastScale - [fingers scale]); 
        newScale = MIN(newScale, maxScale / currentScale);   
        newScale = MAX(newScale, minScale / currentScale);
        CGAffineTransform transform = CGAffineTransformScale([[fingers view] transform], newScale, newScale);
        viewToZoom.transform = transform;

        lastScale = [fingers scale];  // Store the previous scale factor for the next pinch gesture call  
    }

    [dict setObject:[NSNumber numberWithFloat:lastScale] 
             forKey:@"lastScale"];

}

- (void)fingerDidMoveInDraggableView:(UIPanGestureRecognizer *)finger {
    NSMutableDictionary *dict = [self dictForViewGuestures:finger];
    UIView *viewToDrag =  finger.view;
    if (finger.state == UIGestureRecognizerStateBegan) {

        [dict setObject:[NSValue valueWithCGPoint:viewToDrag.frame.origin] 
                 forKey:@"startDragOffset"];

        [dict setObject:[NSValue valueWithCGPoint:[finger locationInView:self.view]] 
                 forKey:@"startDragLocation"];


    }
    else if (finger.state == UIGestureRecognizerStateChanged) {

        NSMutableDictionary *dict = (NSMutableDictionary*) (void*) viewToDrag.tag;

        CGPoint stopLocation = [finger locationInView:self.view];
        CGPoint startDragLocation = [[dict valueForKey:@"startDragLocation"] CGPointValue];
        CGPoint startDragOffset = [[dict valueForKey:@"startDragOffset"] CGPointValue];
        CGFloat dx = stopLocation.x - startDragLocation.x;
        CGFloat dy = stopLocation.y - startDragLocation.y;
        //   CGFloat distance = sqrt(dx*dx + dy*dy );
        CGRect dragFrame = viewToDrag.frame;


        CGSize selfViewSize = self.view.frame.size;
        if (!UIDeviceOrientationIsPortrait(self.interfaceOrientation)) {
            selfViewSize = CGSizeMake(selfViewSize.height,selfViewSize.width);
        }

        selfViewSize.width  -= dragFrame.size.width;
        selfViewSize.height -= dragFrame.size.height;

        dragFrame.origin.x = MIN(selfViewSize.width, MAX(0,startDragOffset.x+dx));
        dragFrame.origin.y = MIN(selfViewSize.height,MAX(0,startDragOffset.y+dy));

        viewToDrag.frame = dragFrame;
    }
    else if (finger.state == UIGestureRecognizerStateEnded) {

        [dict removeObjectForKey:@"startDragLocation"];
        [dict removeObjectForKey:@"startDragOffset"];
    }
}

-(void) makeView:(UIView*)aView 
       draggable:(BOOL)draggable 
       pinchable:(BOOL)pinchable 
   minPinchScale:(CGFloat)minPinchScale
   maxPinchScale:(CGFloat)maxPinchScale{
    NSMutableDictionary *dict = (NSMutableDictionary*) (void*) aView.tag;

    if (!(pinchable || draggable)) {

        if (dict){ 
            [dict release];
            aView.tag = 0;
        }
        return;
    }

    if (dict) {

        UIPanGestureRecognizer *pan =[dict objectForKey:@"UIPanGestureRecognizer"];
        if(pan){
            if ([aView.gestureRecognizers indexOfObject:pan]!=NSNotFound) {
                [aView removeGestureRecognizer:pan];
            }
            [dict removeObjectForKey:@"UIPanGestureRecognizer"];
        }

        UIPinchGestureRecognizer *pinch =[dict objectForKey:@"UIPinchGestureRecognizer"];
        if(pinch){
            if ([aView.gestureRecognizers indexOfObject:pinch]!=NSNotFound) {
                [aView removeGestureRecognizer:pinch];
            }
            [dict removeObjectForKey:@"UIPinchGestureRecognizer"];
        }

        [dict removeObjectForKey:@"startDragLocation"];
        [dict removeObjectForKey:@"startDragOffset"];
        [dict removeObjectForKey:@"lastScale"];
        [dict removeObjectForKey:@"minScale"];
        [dict removeObjectForKey:@"maxScale"];
    }


    if (draggable) {

        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(fingerDidMoveInDraggableView:)];
        pan.minimumNumberOfTouches = 1;  
        pan.maximumNumberOfTouches = 1;  
        [aView addGestureRecognizer:pan];
        [pan release];

        dict = [self dictForViewGuestures:pan];
        [dict setObject:pan forKey:@"UIPanGestureRecognizer"];

    }

    if (pinchable) {


        CGAffineTransform initialTramsform = CGAffineTransformMakeScale(1.0, 1.0);
        aView.transform = initialTramsform;


        UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(fingersDidPinchInPinchableView:)];
        [aView addGestureRecognizer:pinch];
        [pinch release];
        dict = [self dictForViewGuestures:pinch];
        [dict setObject:pinch forKey:@"UIPinchGestureRecognizer"];
        [dict setObject:[NSNumber numberWithFloat:minPinchScale] forKey:@"minScale"];
        [dict setObject:[NSNumber numberWithFloat:maxPinchScale] forKey:@"maxScale"];


    }

}

@end

【讨论】:

  • 感谢它在我的代码中运行良好。我长期以来一直面临这个问题,但你上面的代码帮助我解决了这个问题。再次感谢
【解决方案4】:

大多数其他答案的问题是他们试图将比例作为线性值处理,而实际上它是非线性的,因为UIPinchGestureRecognizer 根据触摸距离计算其比例属性的方式。如果不考虑这一点,用户必须使用或多或少的捏合距离来“撤消”先前捏合手势应用的缩放。

考虑:假设transform.scale = 1.0,我将手指放在屏幕上相距 6 厘米,然后向内捏到相距 3 厘米 - 结果gestureRecognizer.scale0.50.5-1.0-0.5,所以transform.scale 会变成1.0+(-0.5) = 0.5。现在,我抬起手指,将它们放回原处,相距 3 厘米,然后向外捏到 6 厘米。结果gestureRecognizer.scale 将是2.02.0-1.01.0,所以transform.scale 将变为0.5+1.0 = 1.5。不是我想要发生的。

解决方法是计算增量收缩比例作为其先前值的比例。我将手指向下分开 6 厘米,然后向内捏到 3 厘米,所以gestureRecognizer.scale0.50.5/1.00.5,所以我的新 transform.scale1.0*0.5 = 0.5。接下来,我将手指向下分开 3 厘米,然后向外捏到 6 厘米。 gestureRecognizer.scale2.02.0/1.02.0,所以我的新 transform.scale0.5*2.0 = 1.0,这正是我想要发生的。

代码如下:

-(void)viewDidLoad:

self.zoomGestureCurrentZoom = 1.0f;

-(void)onZoomGesture:(UIPinchGestureRecognizer*)gestureRecognizer:

if ( gestureRecognizer.state == UIGestureRecognizerStateBegan )
{
    self.zoomGestureLastScale = gestureRecognizer.scale;
}
else if ( gestureRecognizer.state == UIGestureRecognizerStateChanged )
{
    // we have to jump through some hoops to clamp the scale in a way that makes the UX intuitive
    float scaleDeltaFactor = gestureRecognizer.scale/self.zoomGestureLastScale;
    float currentZoom = self.zoomGestureCurrentZoom;
    float newZoom = currentZoom * scaleDeltaFactor;
    // clamp
    float kMaxZoom = 4.0f;
    float kMinZoom = 0.5f;
    newZoom = MAX(kMinZoom,MIN(newZoom,kMaxZoom));    
    self.view.transform = CGAffineTransformScale([[gestureRecognizer view] transform], newZoom, newZoom);

    // store for next time
    self.zoomGestureCurrentZoom = newZoom;
    self.zoomGestureLastScale = gestureRecognizer.scale;
}

【讨论】:

  • 当我将它设置为特定视图时,这对我不起作用,gestureRecognizer.view 我遇到了多个捏合的“速度”不同的问题,我认为这就是你的意思。
  • @PaulSolt 嗯,是的.. 我想我在哪里得到了[[gestureRecognizer view] transform],这可能是CGAffineTransformIdentity?我认为在我基于此的代码中,self.view 应该与gestureRecognizer.view 不同。不记得对不起:/
【解决方案5】:

谢谢,非常有用的代码 sn-p 以上钳制到最小和最大规模。

我发现当我第一次使用以下方法翻转视图时:

CGAffineTransformScale(gestureRecognizer.view.transform, -1.0, 1.0); 

缩放视图时会导致闪烁。

让我知道你的想法,但我的解决方案是更新上面的代码示例,如果视图已翻转(通过属性设置标志),则反转比例值:

if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer     state] == UIGestureRecognizerStateChanged)
{
    CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];

    if(self.isFlipped) // (inverting)
    {
        currentScale *= -1;
    }

    CGFloat newScale = 1 -  (self.lastScale - [gestureRecognizer scale]);

    newScale = MIN(newScale, self.maximumScaleFactor / currentScale);
    newScale = MAX(newScale, self.minimumScaleFactor / currentScale);

    CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
    gestureRecognizer.view.transform = transform;

    self.lastScale = [gestureRecognizer scale];  // Store the previous scale factor for the next pinch gesture call

【讨论】:

    【解决方案6】:

    方法一

    gestureRecognizer.scale 在捏的开头从 1.0 (gestureRecognizer.state == .began) 开始,以后状态(.changed 或 .end)的gestureRecognizer.scale 始终基于此例如,如果在pinch开始时视图大小为view_size(可能与原始大小orig_view_size不一样),gestureRecognizer.scale总是以1.0开头,如果之后变成2.0,它的大小将是2 * view_size,因此比例始终基于捏合开始时的比例。

    我们可以得到在捏开始时的比例(gestureRecognizer.state == .began)lastScale = self.imageView.frame.width/self.imageView.bounds.size.width,所以现在原始图像的比例应该是lastScale * gestureRecognizer.scale

    • lastScale:最后一轮Pinch的比例,一轮Pinch是从state.start到state.end,比例以原始视图大小为准。

    • gestureRecognizer.scale:当前比例,基于上一轮捏合后的视图大小。

    • currentScale:当前比例,基于原始视图大小。

    • newScale:基于原始视图大小的新比例。 newScale = lastScale * gestureRecognizer.scale,您可以通过将限制与newScale进行比较来限制视图的比例。

    ```

    var lastScale:CGFloat = 1.0
    
    @objc func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer) {
            var newScale = gestureRecognizer.scale
            if gestureRecognizer.state == .began {
                lastScale = self.imageView.frame.width/self.imageView.bounds.size.width
            }
            newScale = newScale * lastScale
    
            if newScale < minScale {
                newScale = minScale
            } else if newScale > maxScale {
                newScale = maxScale
            }
    
            let currentScale = self.imageView.frame.width/self.imageView.bounds.size.width
            self.imageView.transform = CGAffineTransform(scaleX: newScale, y: newScale)
            print("last Scale: \(lastScale), current scale: \(currentScale), new scale: \(newScale), gestureRecognizer.scale: \(gestureRecognizer.scale)")
    }
    

    ```

    方法二

    gestureRecognizer.scale 在每个 Pinch 通知上从 1.0 开始,这需要您在每个通知处理程序末尾的代码中重置 gestureRecognizer.scale = 1,所以现在 gestureRecognizer.scale 基于视图大小最后一次捏合通知,不基于捏合开始时的视图大小。这是与方法1最重要的区别。由于我们不依赖上一轮的规模,我们不再需要lastScale

    • currentScale:当前比例,基于原始视图大小。

    • gestureRecognizer.scale: 新的比例尺,基于最后一个Pinch(不是最后一轮)的视图尺寸,基于原始视图尺寸的比例尺值为currentScale * gestureRecognizer.scale

    我们现在使用transform.scaledBy,它使用基于最后一个捏(不是最后一轮)的视图大小的比例。

    ```

    @objc func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer) {
            let currentScale = self.imageView.frame.width/self.imageView.bounds.size.width
            var newScale = gestureRecognizer.scale
            if currentScale * gestureRecognizer.scale < minScale {
                newScale = minScale / currentScale
            } else if currentScale * gestureRecognizer.scale > maxScale {
                newScale = maxScale / currentScale
            }
            self.imageView.transform = self.imageView.transform.scaledBy(x: newScale, y: newScale)
    
            print("current scale: \(currentScale), new scale: \(newScale)")
    
            gestureRecognizer.scale = 1
    }
    

    ```

    【讨论】:

    • 只有你的代码是 Swift 的。那么,maxScale 和 minScale 的初始值是多少呢?
    • @EmreDeğirmenci,我将 minScale 设置为 1,将 maxScale 设置为 5
    【解决方案7】:

    这里提到的其他方法对我不起作用,但是从以前的答案中提取一些东西并(在我看来)简化事情,我已经得到了这个对我有用。 effectiveScale 是在 viewDidLoad 中设置为 1.0 的 ivar。

    -(void)zoomScale:(UIPinchGestureRecognizer *)recognizer
    {
        if([recognizer state] == UIGestureRecognizerStateEnded) {
            // Reset last scale
            lastScale = 1.0;
            return;
        }
    
        if ([recognizer state] == UIGestureRecognizerStateBegan ||
        [recognizer state] == UIGestureRecognizerStateChanged) {
    
            CGFloat pinchscale = [recognizer scale];
            CGFloat scaleDiff = pinchscale - lastScale;
    
            if (scaleDiff < 0)
                scaleDiff *= 2; // speed up zoom-out
            else
                scaleDiff *= 0.7; // slow down zoom-in
    
            effectiveScale += scaleDiff;
            // Limit scale between 1 and 2
            effectiveScale = effectiveScale < 1 ? 1 : effectiveScale;
            effectiveScale = effectiveScale > 2 ? 2 : effectiveScale;
    
            // Handle transform in separate method using new effectiveScale    
            [self makeAndApplyAffineTransform];
            lastScale = pinchscale;
        }
    }
    

    【讨论】:

    • 这是处理手势识别器 scale 属性中固有的非线性的一种有点复杂的方法,而且它实际上并没有正确处理它,它只是按 0.7 缩放。请参阅我的答案以获得更好的方法:)
    【解决方案8】:
    - (void)handlePinch:(UIPinchGestureRecognizer *)recognizer{
    
        //recognizer.scale=1;
    
        CGFloat pinchScale = recognizer.scale;
        pinchScale = round(pinchScale * 1000) / 1000.0;
        NSLog(@"%lf",pinchScale);
    
    if (pinchScale < 1)
    
     {
    
     currentLabel.font = [UIFont fontWithName:currentLabel.font.fontName size:
    
    (currentLabel.font.pointSize - pinchScale)];
    
       recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    
     [currentLabel sizeToFit];
    
      recognizer.scale=1;
        }
      else
        {
            currentLabel.font = [UIFont fontWithName:currentLabel.font.fontName size:(currentLabel.font.pointSize + pinchScale)];
    
             recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    
             [currentLabel sizeToFit];
    
            recognizer.scale=1;
        }
        //currentLabel.adjustsFontSizeToFitWidth = YES;
    
       // [currentLabel sizeToFit];
        NSLog(@"Font :%@",label.font);
    }
    

    【讨论】:

    • ohhhh 太好了,它真的很好用,谢谢......!!但是我想用这种方法改变我的标签框架,我尝试了它,但它不能在水平和垂直方向上完美地工作,它会改变它的高度和宽度,所以你能帮我解决这个问题...... THX...... Arvind Kumar 先生...... :)
    【解决方案9】:
    - (void)pinchToZoom:(UIPinchGestureRecognizer*)gesture
    {
        switch (gesture.state)
        {
            case UIGestureRecognizerStateBegan:
            {
                lastScale = gesture.scale;
            }break;
            case UIGestureRecognizerStateChanged:
            {   
                const CGFloat zoomSensitivity = 5;
                const CGFloat zoomMin = 1;
                const CGFloat zoomMax = 16;
    
                CGFloat objectScale = gesture.view.contentScaleFactor;
                CGFloat zoomDiff = lastScale - gesture.scale;
                CGFloat zoomDirty = objectScale - zoomDiff * zoomSensivity;
                CGFloat zoomTo = fmaxf(zoomMin, fminf(zoomDirty, zoomMax));
    
                // step round if needed (neutralize elusive changes)
                zoomTo = (NSInteger)(zoomTo * 10) * 0.1;
    
                if ( objectScale != zoomTo )
                    gesture.view.contentScaleFactor = zoomTo;
    
                lastScale = gesture.scale;
            }break;
            default:
                break;
        }
    }
    

    【讨论】:

      【解决方案10】:

      我采用了@Paul Solt 解决方案 - 顺便说一句,这很棒,并将其改编为 Swift,供感兴趣的人使用

      @objc func pinchUpdated(recognizer: UIPinchGestureRecognizer) {
              
              if recognizer.state == .began {
                  // Reset the last scale, necessary if there are multiple objects with different scales
                  lastScale = recognizer.scale
              }
      
              if recognizer.state == .began || recognizer.state == .changed {
      
                  let currentScale = recognizer.view!.layer.value(forKeyPath: "transform.scale") as! CGFloat
      
                  // Constants to adjust the max/min values of zoom
                  let maxScale: CGFloat = 4.0
                  let ninScale: CGFloat = 0.9
      
                  var newScale: CGFloat = 1 -  (lastScale - recognizer.scale)
                  newScale = min(newScale, maxScale / currentScale)
                  newScale = max(newScale, ninScale / currentScale)
                  recognizer.view!.transform = recognizer.view!.transform.scaledBy(x: newScale, y: newScale)
      
                  lastScale = recognizer.scale // Store the previous scale factor for the next pinch gesture call
              }
          }
      

      【讨论】:

        【解决方案11】:

        你能用滚动视图代替吗?然后你可以使用 scrollView.minimumZoomScale 和 scrollView.maximumZoomScale

        【讨论】:

        • 嗯,很有趣...将把它作为解决问题的替代方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-11
        • 1970-01-01
        • 1970-01-01
        • 2015-05-31
        相关资源
        最近更新 更多