【问题标题】:Using UIPinchGestureRecognizer to scale uiviews in single direction使用 UIPinchGestureRecognizer 单向缩放 uiviews
【发布时间】:2014-04-25 14:12:30
【问题描述】:

我想知道我们如何使用UIPinchGestureRecognizer 仅在单个(x 或 y)方向上缩放UIView。比如说,如果用户只在一个方向(水平)上以捏合手势移动他的两个手指,那么只有 uiview 的宽度应该增加/减少,如果手指只垂直移动,高度应该改变。如果手指沿对角线移动,则 uiview 的高度和宽度都应该增加/减少。我看过 Apple 的 MoveMe 示例代码。

UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scalePiece:)];
[pinchGesture setDelegate:self];
[piece addGestureRecognizer:pinchGesture];
[pinchGesture release];

鳞片:

- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer
{
    UIView *piece = (UIView *) [gestureRecognizer view];
    NSLog(@"scalePiece enter");
    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan){
          NSLog(@"inside if");
          lastTouchPosition = [gestureRecognizer locationInView:piece];
    } 
    else if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged){
          NSLog(@"inside else");
          CGPoint currentTouchLocation = [gestureRecognizer locationInView:piece];
          NSLog(@"currentTouchLocation = %@ and lastTouchPosition= %@",NSStringFromCGPoint(currentTouchLocation), NSStringFromCGPoint(lastTouchPosition));
          CGPoint deltaMove = [self calculatePointDistancewithPoint1:currentTouchLocation andPoint2:lastTouchPosition];
          NSLog(@"deltaMove = %@",NSStringFromCGPoint(deltaMove));
          float distance = sqrt(deltaMove.x*deltaMove.x + deltaMove.y*deltaMove.y);
          NSLog(@"distance = %f",distance);
          float hScale = 1 - deltaMove.x/distance * (1-gestureRecognizer.scale);
          float vScale = 1 - deltaMove.y/distance * (1-gestureRecognizer.scale);
          if (distance == 0) {
                     hScale = 1;
                     vScale = 1;
          }
          NSLog(@"[gestureRecognizer scale] = %f",[gestureRecognizer scale]);
          NSLog(@"hScale = %f and vScale = %f",hScale, vScale);
          piece.transform = CGAffineTransformScale([piece transform], hScale, vScale);
          [gestureRecognizer setScale:1];
          lastTouchPosition = currentTouchLocation;
    }
    NSLog(@"scalePiece exit");
}

计算距离:

- (CGPoint) calculatePointDistancewithPoint1:(CGPoint)point1 andPoint2:(CGPoint) point2 {
    return CGPointMake(point2.x - point1.x, point2.y - point1.y);
}

这是当我试图捏出(放大)视图时仅在垂直方向上移动手指时的日志输出。元素的高度没有增加。

2011-07-21 13:06:56.245 New[8169:707] scalePiece enter
2011-07-21 13:06:56.248 New[8169:707] inside if
2011-07-21 13:06:56.251 New[8169:707] scalePiece exit
2011-07-21 13:06:56.259 New[8169:707] scalePiece enter
2011-07-21 13:06:56.262 New[8169:707] inside else
2011-07-21 13:06:56.264 New[8169:707] currentTouchLocation = {88, 87} and lastTouchPosition= {87, 86}
2011-07-21 13:06:56.265 New[8169:707] deltaMove = {-1, -1}
2011-07-21 13:06:56.267 New[8169:707] distance = 1.414214
2011-07-21 13:06:56.268 New[8169:707] [gestureRecognizer scale] = 1.102590
2011-07-21 13:06:56.271 New[8169:707] hScale = 0.927458 and vScale = 0.927458
2011-07-21 13:06:56.272 New[8169:707] scalePiece exit
2011-07-21 13:06:56.281 New[8169:707] scalePiece enter
2011-07-21 13:06:56.283 New[8169:707] inside else
2011-07-21 13:06:56.284 New[8169:707] currentTouchLocation = {87, 89} and lastTouchPosition= {88, 87}
2011-07-21 13:06:56.286 New[8169:707] deltaMove = {1, -2}
2011-07-21 13:06:56.287 New[8169:707] distance = 2.236068
2011-07-21 13:06:56.296 New[8169:707] [gestureRecognizer scale] = 1.096172
2011-07-21 13:06:56.298 New[8169:707] hScale = 1.043009 and vScale = 0.913981
2011-07-21 13:06:56.299 New[8169:707] scalePiece exit
2011-07-21 13:06:56.302 New[8169:707] scalePiece enter
2011-07-21 13:06:56.303 New[8169:707] inside else
2011-07-21 13:06:56.305 New[8169:707] currentTouchLocation = {88, 89} and lastTouchPosition= {87, 89}
2011-07-21 13:06:56.309 New[8169:707] deltaMove = {-1, 0}
2011-07-21 13:06:56.311 New[8169:707] distance = 1.000000
2011-07-21 13:06:56.313 New[8169:707] [gestureRecognizer scale] = 1.066320
2011-07-21 13:06:56.314 New[8169:707] hScale = 0.933680 and vScale = 1.000000
2011-07-21 13:06:56.316 New[8169:707] scalePiece exit
2011-07-21 13:06:56.318 New[8169:707] scalePiece enter
2011-07-21 13:06:56.320 New[8169:707] inside else
2011-07-21 13:06:56.329 New[8169:707] currentTouchLocation = {88, 90} and lastTouchPosition= {88, 89}
2011-07-21 13:06:56.331 New[8169:707] deltaMove = {0, -1}
2011-07-21 13:06:56.333 New[8169:707] distance = 1.000000
2011-07-21 13:06:56.334 New[8169:707] [gestureRecognizer scale] = 1.061696
2011-07-21 13:06:56.335 New[8169:707] hScale = 1.000000 and vScale = 0.938304
2011-07-21 13:06:56.338 New[8169:707] scalePiece exit
2011-07-21 13:06:56.343 New[8169:707] scalePiece enter
2011-07-21 13:06:56.346 New[8169:707] inside else
2011-07-21 13:06:56.347 New[8169:707] currentTouchLocation = {88, 92} and lastTouchPosition= {88, 90}
2011-07-21 13:06:56.349 New[8169:707] deltaMove = {0, -2}
2011-07-21 13:06:56.350 New[8169:707] distance = 2.000000
2011-07-21 13:06:56.351 New[8169:707] [gestureRecognizer scale] = 1.096869
2011-07-21 13:06:56.353 New[8169:707] hScale = 1.000000 and vScale = 0.903131
2011-07-21 13:06:56.362 New[8169:707] scalePiece exit
2011-07-21 13:06:56.366 New[8169:707] scalePiece enter
2011-07-21 13:06:56.370 New[8169:707] inside else
2011-07-21 13:06:56.373 New[8169:707] currentTouchLocation = {88, 92} and lastTouchPosition= {88, 92}
2011-07-21 13:06:56.376 New[8169:707] deltaMove = {0, 0}
2011-07-21 13:06:56.380 New[8169:707] distance = 0.000000
2011-07-21 13:06:56.383 New[8169:707] [gestureRecognizer scale] = 1.035330
2011-07-21 13:06:56.387 New[8169:707] hScale = 1.000000 and vScale = 1.000000
2011-07-21 13:06:56.389 New[8169:707] scalePiece exit
2011-07-21 13:06:56.393 New[8169:707] scalePiece enter
2011-07-21 13:06:56.397 New[8169:707] inside else
2011-07-21 13:06:56.399 New[8169:707] currentTouchLocation = {88, 93} and lastTouchPosition= {88, 92}
2011-07-21 13:06:56.403 New[8169:707] deltaMove = {0, -1}
2011-07-21 13:06:56.406 New[8169:707] distance = 1.000000
2011-07-21 13:06:56.409 New[8169:707] [gestureRecognizer scale] = 1.042659
2011-07-21 13:06:56.412 New[8169:707] hScale = 1.000000 and vScale = 0.957341
2011-07-21 13:06:56.414 New[8169:707] scalePiece exit
2011-07-21 13:06:56.419 New[8169:707] scalePiece enter
2011-07-21 13:06:56.422 New[8169:707] inside else
2011-07-21 13:06:56.425 New[8169:707] currentTouchLocation = {88, 92} and lastTouchPosition= {88, 93}
2011-07-21 13:06:56.427 New[8169:707] deltaMove = {0, 1}
2011-07-21 13:06:56.430 New[8169:707] distance = 1.000000
2011-07-21 13:06:56.432 New[8169:707] [gestureRecognizer scale] = 1.024549
2011-07-21 13:06:56.436 New[8169:707] hScale = 1.000000 and vScale = 1.024549
2011-07-21 13:06:56.439 New[8169:707] scalePiece exit
2011-07-21 13:06:56.442 New[8169:707] scalePiece enter
2011-07-21 13:06:56.447 New[8169:707] inside else
2011-07-21 13:06:56.450 New[8169:707] currentTouchLocation = {88, 92} and lastTouchPosition= {88, 92}
2011-07-21 13:06:56.453 New[8169:707] deltaMove = {0, 0}
2011-07-21 13:06:56.455 New[8169:707] distance = 0.000000
2011-07-21 13:06:56.458 New[8169:707] [gestureRecognizer scale] = 1.007702
2011-07-21 13:06:56.460 New[8169:707] hScale = 1.000000 and vScale = 1.000000
2011-07-21 13:06:56.464 New[8169:707] scalePiece exit
2011-07-21 13:06:56.501 New[8169:707] scalePiece enter
2011-07-21 13:06:56.504 New[8169:707] inside else
2011-07-21 13:06:56.507 New[8169:707] currentTouchLocation = {89, 92} and lastTouchPosition= {88, 92}
2011-07-21 13:06:56.509 New[8169:707] deltaMove = {-1, 0}
2011-07-21 13:06:56.510 New[8169:707] distance = 1.000000
2011-07-21 13:06:56.511 New[8169:707] [gestureRecognizer scale] = 1.000283
2011-07-21 13:06:56.513 New[8169:707] hScale = 0.999717 and vScale = 1.000000
2011-07-21 13:06:56.517 New[8169:707] scalePiece exit
2011-07-21 13:06:56.566 New[8169:707] scalePiece enter
2011-07-21 13:06:56.570 New[8169:707] inside else
2011-07-21 13:06:56.572 New[8169:707] currentTouchLocation = {89, 91} and lastTouchPosition= {89, 92}
2011-07-21 13:06:56.573 New[8169:707] deltaMove = {0, 1}
2011-07-21 13:06:56.575 New[8169:707] distance = 1.000000
2011-07-21 13:06:56.576 New[8169:707] [gestureRecognizer scale] = 1.008267
2011-07-21 13:06:56.579 New[8169:707] hScale = 1.000000 and vScale = 1.008267
2011-07-21 13:06:56.582 New[8169:707] scalePiece exit
2011-07-21 13:06:56.585 New[8169:707] scalePiece enter
2011-07-21 13:06:56.586 New[8169:707] inside else
2011-07-21 13:06:56.588 New[8169:707] currentTouchLocation = {89, 91} and lastTouchPosition= {89, 91}
2011-07-21 13:06:56.589 New[8169:707] deltaMove = {0, 0}
2011-07-21 13:06:56.591 New[8169:707] distance = 0.000000
2011-07-21 13:06:56.597 New[8169:707] [gestureRecognizer scale] = 1.000000
2011-07-21 13:06:56.599 New[8169:707] hScale = 1.000000 and vScale = 1.000000
2011-07-21 13:06:56.600 New[8169:707] scalePiece exit
2011-07-21 13:06:56.603 New[8169:707] scalePiece enter
2011-07-21 13:06:56.604 New[8169:707] inside else
2011-07-21 13:06:56.606 New[8169:707] currentTouchLocation = {89, 182} and lastTouchPosition= {89, 91}
2011-07-21 13:06:56.607 New[8169:707] deltaMove = {0, -91}
2011-07-21 13:06:56.617 New[8169:707] distance = 91.000000
2011-07-21 13:06:56.620 New[8169:707] [gestureRecognizer scale] = 1.000000
2011-07-21 13:06:56.623 New[8169:707] hScale = 1.000000 and vScale = 1.000000
2011-07-21 13:06:56.626 New[8169:707] scalePiece exit
2011-07-21 13:06:56.630 New[8169:707] scalePiece enter
2011-07-21 13:06:56.632 New[8169:707] scalePiece exit

【问题讨论】:

    标签: iphone objective-c ios ipad uigesturerecognizer


    【解决方案1】:

    如果我正确理解您的问题,您的目标是沿水平轴和垂直轴进行非比例缩放。在这种情况下,事情归结为提供仿射变换:

      piece.transform = CGAffineTransformScale([piece transform], hScale, vScale);
    

    具有不同的缩放因子。

    计算它们的一种方法如下:

    1. 在你的类中定义一个 ivar 来存储 lastTouchPosition;

    2. 在您的手势处理程序中,您将执行以下操作:

      if ([gestureRecognizer state] == UIGestureRecognizerStateBegan){
      
         lastTouchPosition = [gestureRecognize locationInView:yourViewHere];
         hScale = 1;
         vScale = 1;
      
      } else if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged){
      
         CGPoint currentTouchLocation = [gestureRecognize locationInView:yourViewHere];
         CGPoint deltaMove = CGPointDistance(currentTouchLocation, lastTouchPosition);
         float distance = sqrt(deltaMove.x*deltaMove.x + deltaMove.y*deltaMove.y);
         hScale -= abs(deltaMove.x)/distance * (1-gestureRecognizer.scale);
         vScale -= abs(deltaMove.y)/distance * (1-gestureRecognizer.scale);
         piece.transform = CGAffineTransformScale([piece transform], hScale, vScale);
         [gestureRecognizer setScale:1];
      
         lastTouchPosition = currentTouchLocation;
      }
      

    另一种做法是:

        if ([gestureRecognizer state] == UIGestureRecognizerStateBegan){
    
           lastTouchPosition = [gestureRecognize locationInView:yourViewHere];
    
        } else if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged){
    
           CGPoint currentTouchLocation = [gestureRecognize locationInView:yourViewHere];
           CGPoint deltaMove = CGPointDistance(currentTouchLocation, lastTouchPosition);
           float distance = sqrt(deltaMove.x*deltaMove.x + deltaMove.y*deltaMove.y);
           float hScale = 1 - abs(deltaMove.x)/distance * (1-gestureRecognizer.scale);
           float vScale = 1 - abs(deltaMove.y)/distance * (1-gestureRecognizer.scale);
           piece.transform = CGAffineTransformScale([piece transform], hScale, vScale);
    
           lastTouchPosition = currentTouchLocation;
        }
    

    这不会在每次迭代时存储当前的hFloatvFloat,而是依赖于gestureRecognizer 将累积整体规模变化这一事实。它执行“绝对”计算,而第一个实现执行“相对”计算。

    请注意,您还需要定义 CGPointDistance 来计算两次触摸之间的距离,并选择要使用哪个视图来计算距离 (yourViewHere)。

    编辑:

    CGPoint CGPointDistance(CGPoint point1, CGPoint point2)
    {
        return = CGPointMake(point2.x - point1.x, point2.y - point1.y);
    };
    

    EDIT2:关于计算比例的公式

    这个想法是计算比例因子的变化,并根据它们的相对变化将其应用于两个方向(x 和 y)。

    1. 比例因子增量为:1-gestureRecognizer.scale;

    2. 增量是乘以一个因子,因此它与沿水平或垂直轴的位移成比例;当位移为零时,增量比例也为零;当沿两个轴的位移相等时,沿两个轴的比例增量也相等;我决定除以distance,但还有其他可能性(例如除以两个 deltaMove 的总和或除以 deltaMove 的最大值等)。

    3. 最终从元素的当前比例中减去调整后的增量。

    【讨论】:

    • 是的,我正在查看视图的非比例缩放。我会试试这个并在某个时候在这里更新。感谢您的宝贵时间。
    • 你建议我如何定义 CGPointDistance ?而且, yourViewHere 将是执行捏合手势的视图。最后,您编写的最后一行代码为 lastTouchLocation = currentTouchLocation;不应该是lastTouchPosition吗?
    • 请看编辑。正如你所说,我已经修改了代码。但我将 hScale 和 vScale 设为零。因此视图正在消失。
    • 检查 lastTouchPosition 和 currentTouchLocation... 它们是一样的吗?如果是这样,请尝试使用locationInView:piece.superview...
    • 如果手指只在一个方向上移动,比如水平或垂直,那么对应的h/vScale不会是0.000。我认为计算比例的方式不同。但逻辑是一样的。
    【解决方案2】:

    今天我遇到了同样的问题,我找到了一个简单快捷的方法

    - (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer
    {
      recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale,1);
      recognizer.scale = 1;
    }
    

    【讨论】:

      【解决方案3】:

      我创建了一个自定义版本的 UIPinchGestureRecognizer 来完全满足您的需求。它使用两个手指之间的直线斜率来确定刻度的方向。它有 3 种类型:垂直;水平的;和组合(对角线)。请在底部查看我的笔记。

      -(void) scaleTheView:(UIPinchGestureRecognizer *)pinchRecognizer
          {
          if ([pinchRecognizer state] == UIGestureRecognizerStateBegan || [pinchRecognizer state] == UIGestureRecognizerStateChanged) {
      
          if ([pinchRecognizer numberOfTouches] > 1) {
      
              UIView *theView = [pinchRecognizer view];
      
              CGPoint locationOne = [pinchRecognizer locationOfTouch:0 inView:theView];
              CGPoint locationTwo = [pinchRecognizer locationOfTouch:1 inView:theView];
                  NSLog(@"touch ONE  = %f, %f", locationOne.x, locationOne.y);
                  NSLog(@"touch TWO  = %f, %f", locationTwo.x, locationTwo.y);
              [scalableView setBackgroundColor:[UIColor redColor]];
      
              if (locationOne.x == locationTwo.x) {
                      // perfect vertical line
                      // not likely, but to avoid dividing by 0 in the slope equation
                  theSlope = 1000.0;
              }else if (locationOne.y == locationTwo.y) {
                      // perfect horz line
                      // not likely, but to avoid any problems in the slope equation
                  theSlope = 0.0;
              }else {
                  theSlope = (locationTwo.y - locationOne.y)/(locationTwo.x - locationOne.x);
              }
      
              double abSlope = ABS(theSlope);
      
              if (abSlope < 0.5) {
                          //  Horizontal pinch - scale in the X
                  [arrows setImage:[UIImage imageNamed:@"HorzArrows.png"]];
                  arrows.hidden = FALSE;
                          // tranform.a  = X-axis
                      NSLog(@"transform.A = %f", scalableView.transform.a);
                          // tranform.d  = Y-axis
                      NSLog(@"transform.D = %f", scalableView.transform.d);
      
                          //  if hit scale limit along X-axis then stop scale and show Blocked image
                  if (((pinchRecognizer.scale > 1.0) && (scalableView.transform.a >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.a <= 0.1))) {
                      blocked.hidden = FALSE;
                      arrows.hidden = TRUE;
                  } else {
                              // scale along X-axis
                      scalableView.transform = CGAffineTransformScale(scalableView.transform, pinchRecognizer.scale, 1.0);
                      pinchRecognizer.scale = 1.0;
                      blocked.hidden = TRUE;
                      arrows.hidden = FALSE;
                  }
              }else if (abSlope > 1.7) {
                          // Vertical pinch - scale in the Y
                  [arrows setImage:[UIImage imageNamed:@"VerticalArrows.png"]];
                  arrows.hidden = FALSE;
                      NSLog(@"transform.A = %f", scalableView.transform.a);
                      NSLog(@"transform.D = %f", scalableView.transform.d);
      
                          //  if hit scale limit along Y-axis then don't scale and show Blocked image
                  if (((pinchRecognizer.scale > 1.0) && (scalableView.transform.d >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.d <= 0.1))) {
                      blocked.hidden = FALSE;
                      arrows.hidden = TRUE;
                  } else {
                              // scale along Y-axis
                      scalableView.transform = CGAffineTransformScale(scalableView.transform, 1.0, pinchRecognizer.scale);
                      pinchRecognizer.scale = 1.0;
                      blocked.hidden = TRUE;
                      arrows.hidden = FALSE;
                  }
              } else {
                          // Diagonal pinch - scale in both directions
                  [arrows setImage:[UIImage imageNamed:@"CrossArrows.png"]];
                  blocked.hidden = TRUE;
                  arrows.hidden = FALSE;
      
                      NSLog(@"transform.A = %f", scalableView.transform.a);
                      NSLog(@"transform.D = %f", scalableView.transform.d);
      
                          // if we have hit any limit don't allow scaling
                  if ((((pinchRecognizer.scale > 1.0) && (scalableView.transform.a >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.a <= 0.1))) || (((pinchRecognizer.scale > 1.0) && (scalableView.transform.d >= 2.0)) || ((pinchRecognizer.scale < 1.0) && (scalableView.transform.d <= 0.1)))) {
                      blocked.hidden = FALSE;
                      arrows.hidden = TRUE;
                  } else {
                              // scale in both directions
                      scalableView.transform = CGAffineTransformScale(scalableView.transform, pinchRecognizer.scale, pinchRecognizer.scale);
                      pinchRecognizer.scale = 1.0;
                      blocked.hidden = TRUE;
                      arrows.hidden = FALSE;
                  }
              }  // else for diagonal pinch
          }  // if numberOfTouches
      }  // StateBegan if
      
      if ([pinchRecognizer state] == UIGestureRecognizerStateEnded || [pinchRecognizer state] == UIGestureRecognizerStateCancelled) {
          NSLog(@"StateEnded StateCancelled");
          [scalableView setBackgroundColor:[UIColor whiteColor]];
          arrows.hidden = TRUE;
          blocked.hidden = TRUE;
          }
      }
      

      记得在视图控制器头文件中添加协议:

      @interface WhiteViewController : UIViewController <UIGestureRecognizerDelegate>
      {
      IBOutlet UIView *scalableView;
      IBOutlet UIView *mainView;
      IBOutlet UIImageView *arrows;
      IBOutlet UIImageView *blocked;
      }
      @property (strong, nonatomic) IBOutlet UIView *scalableView;
      @property (strong, nonatomic) IBOutlet UIView *mainView;
      @property (strong, nonatomic)IBOutlet UIImageView *arrows;
      @property (strong, nonatomic)IBOutlet UIImageView *blocked;
      
      -(void) scaleTheView:(UIPinchGestureRecognizer *)pinchRecognizer;
      @end
      

      并在 viewDidLoad 中添加识别器:

      - (void)viewDidLoad
      { UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scaleTheView:)];
      [pinchGesture setDelegate:self];
      [mainView addGestureRecognizer:pinchGesture];
      
      arrows.hidden = TRUE;
      blocked.hidden = TRUE;
      [scalableView setBackgroundColor:[UIColor whiteColor]];}
      

      这是设置为使用主视图来捕捉捏合;并操纵第二个视图。这样,您仍然可以在视图变小时对其进行缩放。您可以将其更改为直接对可扩展视图做出反应。

      限制:我任意选择了视图的起始大小,因此 2.0 的比例限制将等于全屏。我的下限设置为 0.1。

      用户交互:我搞砸了很多用户交互,比如更改视图的背景颜色和在视图上添加/更改箭头以显示方向。在缩放过程中向他们提供反馈很重要,尤其是在像此代码允许的那样更改方向时。

      BUG:Apple 的 UIPinchGestureRecognizer 中有一个错误。如您所料,它通过两根手指的触摸注册 UIGestureRecognizerStateBegan。但是一旦它处于 StateBegan 或 StateChanged 中,您只需抬起一根手指,状态就会保持不变。在两个手指都抬起之前,它不会移动到 StateEnded 或 StateCancelled。这在我的代码中造成了一个错误,并且让我很头疼! if numberOfTouches > 1 修复它。

      未来:您可以将坡度设置更改为仅在一个方向或仅在 2 个方向上缩放。如果添加箭头图像,您可以在旋转手指时看到它们发生变化。

      【讨论】:

      • 谢谢你。能否提供github项目或完整代码。
      猜你喜欢
      • 2014-04-08
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多