通过 CGAffineTransformScale 计算的 bounds、frame 和 frame 之间的差异

Posted

技术标签:

【中文标题】通过 CGAffineTransformScale 计算的 bounds、frame 和 frame 之间的差异【英文标题】:Discrepancies between bounds, frame, and frame calculated through CGAffineTransformScale 【发布时间】:2011-10-31 22:34:48 【问题描述】:

我有一个简单的应用程序,它在屏幕上放置一个图像视图,并允许用户使用捏合和平移手势识别器移动和缩放它。在我的 uipangesturerecognizer 委托方法(比例)中,我试图在使用 CGAffineTransformScale 实际执行转换之前计算转换帧的值。但是,我没有得到正确的值,并且得到了一些与转换后的框架不相符的奇怪结果。下面是我的方法:

- (void)scale:(UIPinchGestureRecognizer *)sender 

    if([sender state] == UIGestureRecognizerStateBegan) 
    
        lastScale = [sender scale];
    

    if ([sender state] == UIGestureRecognizerStateBegan || 
        [sender state] == UIGestureRecognizerStateChanged) 
    
        CGFloat currentScale = [[[sender view].layer valueForKeyPath:@"transform.scale"] floatValue];
        CGFloat newScale = 1 -  (lastScale - [sender scale]) * (CropThePhotoViewControllerPinchSpeed); 

        newScale = MIN(newScale, CropThePhotoViewControllerMaxScale / currentScale);   
        newScale = MAX(newScale, CropThePhotoViewControllerMinScale / currentScale);

        NSLog(@"currentBounds: %@", NSStringFromCGRect([[sender view] bounds]));
        NSLog(@"currentFrame: %@", NSStringFromCGRect([[sender view] frame]));

        CGAffineTransform transform = CGAffineTransformScale([[sender view] transform], newScale, newScale);
        CGRect nextFrame = CGRectApplyAffineTransform([[sender view] frame], transform);

        NSLog(@"nextFrame: %@", NSStringFromCGRect(nextFrame));

        //NSLog(@"nextBounds: %@", NSStringFromCGRect(nextBounds));

        [sender view].transform = transform;
        lastScale = [sender scale];

     

这是我得到的打印结果:

/* currentBounds: 0, 0, 316, 236.013 
   currentFrame: -115.226,-53.4392, 543.452, 405.891 
   nextFrame: -202.566, -93.9454, 955.382, 713.551 */

有了这些结果,currentBounds 坐标显然是 0,0 和往常一样,并且大小和宽度是原始图像在变换之前的大小和宽度。无论我进行多少次转换,这个值似乎都保持不变。

currentFrame 是基于图像在其转换状态下的当前状态的正确坐标以及正确的大小和宽度。

nextFrame 不正确,它应该与下一组打印的值中的 currentFrame 匹配,但它不匹配。

所以我有一些问题:

1) 为什么 currentFrame 显示正确的帧值?我认为执行转换后框架无效?这组值是在我用手指对图像进行多次放大和最小化后显示的。看起来 currentBounds 的高度和宽度是我对 currentFrame 的期望。

2) 为什么我的下一帧值计算不正确,在实际执行转换之前如何准确计算转换帧的值?

【问题讨论】:

【参考方案1】:

您需要将新的转换应用到视图的未转换框架。试试这个:

    CGAffineTransform transform = CGAffineTransformScale([[sender view] transform], newScale, newScale);
    CGAffineTransform iTransform = CGAffineTransformInvert([[sender view] transform]);
    CGRect rawFrame = CGRectApplyAffineTransform([[sender view] frame], iTransform);
    CGRect nextFrame = CGRectApplyAffineTransform(rawFrame, transform);

【讨论】:

谢谢。这完成了缩放高度和宽度的工作,但原点 x 和 y 值出现倾斜。有没有办法解决这个问题,或者它是如何出现的? View Programming Guide for ios 的“坐标系变换”部分说:“修改视图的变换属性时,所有变换都相对于视图的中心点执行。”所以是的,如果您的变换包含缩放或旋转,您的视图框架的原点通常会移动,因为原点不在中心。

以上是关于通过 CGAffineTransformScale 计算的 bounds、frame 和 frame 之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

将 CGAffineTransformScale 与 UIAttachmentBehavior (UIDynamicAnimator) 一起使用

使用 CGAffineTransformScale 自定义 UIView 缩放

求解答CGAffineTransformScale造成字体模糊的问题

求解答CGAffineTransformScale造成字体模糊的问题

如何使用 CGAffineTransform Scale 从右到左添加动画和放大动画

CGAffineTransform