使用捏合手势时,uiview 的边界是不是会发生变化?

Posted

技术标签:

【中文标题】使用捏合手势时,uiview 的边界是不是会发生变化?【英文标题】:Does the bounds of a uiview change when a pinch gesture is used on it?使用捏合手势时,uiview 的边界是否会发生变化? 【发布时间】:2011-08-30 11:30:13 【问题描述】:

我正在使用 UIPinchGestureRecognizer 来扩展/缩小 uiview。

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

//缩放元素方法

- (void)scaleElement:(UIPinchGestureRecognizer *)gestureRecognizer 
    UIView *element = [gestureRecognizer view];
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan)
        lastTouchPosition = [gestureRecognizer locationInView:element];
     
    else if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)
            CGPoint currentTouchPosition = [gestureRecognizer locationInView:element];
            CGPoint deltaMove = [self calculatePointDistancewithPoint1:currentTouchPosition andPoint2:lastTouchPosition];
            float distance = sqrt(deltaMove.x*deltaMove.x + deltaMove.y*deltaMove.y);
            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;
            
            element.transform = CGAffineTransformScale([element transform], hScale, vScale);
            CGAffineTransform transform = CGAffineTransformMakeScale(hScale, vScale);
            element.bounds = CGRectApplyAffineTransform(element.bounds, transform);
                [gestureRecognizer setScale:1];
                lastTouchPosition = currentTouchPosition;
            
            if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) 
                NSLog(@"scaling over");
                NSLog(@"bounds = %@",NSStringFromCGRect(element.bounds));
                NSLog(@"frame = %@", NSStringFromCGRect(element.frame));
            
            NSLog(@"scalePiece exit");
    

//adjustAnchorPointForGestureRecognizer method

    - (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
        if (gestureRecognizer.state == UIGestureRecognizerStateBegan) 
            UIView *elementToAdjust = gestureRecognizer.view;
            [self.view bringSubviewToFront:gestureRecognizer.view];
            CGPoint locationInView = [gestureRecognizer locationInView:elementToAdjust];
            CGPoint locationInSuperview = [gestureRecognizer locationInView:elementToAdjust.superview];
            elementToAdjust.layer.anchorPoint = CGPointMake(locationInView.x / elementToAdjust.bounds.size.width, locationInView.y / elementToAdjust.bounds.size.height);
            elementToAdjust.center = locationInSuperview;
        
    

控制台打印:

bounds = 0, 0, 178.405, 179.018
frame = 300.642, 566.184, 192.899, 194.227

为什么当框架改变时边界没有调整? 由于我对此视图有子视图,因此它与自动调整蒙版大小有关吗?

【问题讨论】:

【参考方案1】:

这与UIPinchGestureRecognizer 无关。这与您设置 transform 以执行缩放有关。更改 transform 不会更改 bounds。它只是改变了这个视图的坐标空间(bounds)如何映射到父视图的坐标空间(frame)。如果你需要bounds匹配frame,你必须直接更改其中一个,而不是使用transform。也就是说,您通常应该使用transform,因为它更快。

编辑

如果您不是要缩放,而是要调整视图大小,请致电setBounds:。您可以通过将转换应用于bounds 而不是元素来找到新的bounds

CGPoint currentTouchPosition = [gestureRecognizer locationInView:element];
CGPoint deltaMove = [self calculatePointDistancewithPoint1:currentTouchPosition andPoint2:lastTouchPosition];
...

CGAffineTransform transform = CGAffineTransformMakeScale(hScale, vScale);
self.bounds = CGRectApplyAffineTransform(self.bounds, transform);

【讨论】:

那么你建议我如何改变视图的边界? gestureRecognizer 没有属性转换。你的意思是 [gestureRecognizer view].transform 吗? CGAffineTransformMakeScale()。固定。 抱歉回复晚了。这样做之后,框架和边界仍然不一样。我正在更新问题。请仔细查看。 您仍在设置element.transform。如果您还设置了bounds,则不应该这样做。

以上是关于使用捏合手势时,uiview 的边界是不是会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章

在 MPMoviePlayerController 上执行捏合手势时屏幕黑屏

UIImageView 上的捏合、平移和双击手势

如果视图注册平移手势,则捏合手势不起作用

SceneKit 相机节点在捏合手势时重置

SwiftUI:调整 ScrollView 的边界

iPhone UIView touchesMoved: withEvent: 不会在 UIView 上使用手势识别器调用