gpt4 book ai didi

iphone - 使用 UIPinchGestureRecognizer 单方向缩放 uiviews

转载 作者:可可西里 更新时间:2023-11-01 03:37:59 25 4
gpt4 key购买 nike

我想知道如何使用 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);
}

这是当我尝试捏出(放大) View 时仅在垂直方向移动我的手指时的日志输出。元素的高度不会增加。

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

最佳答案

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

  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 来计算两次触摸之间的距离,并选择要使用哪个 View 来计算距离(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,但还有其他可能性(例如除以两个 deltaMoves 的总和或除以 deltaMoves 的最大值等)。

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

关于iphone - 使用 UIPinchGestureRecognizer 单方向缩放 uiviews,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6759028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com