3

我在 x 和 y 方向上将 UIBezierPath(由一个 [0,0 - 1x1] rect 构建)缩放 2 倍。UIBezierPath ".bounds" 没问题(即按预期缩放),而 ".CGPath" 保持不变......

代码:

#import <UIKit/UIKit.h>

int main(int argc, char *argv[])
{
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0,
                                                                     1, 1)];
    NSLog(@"path.bounds box before transform:%@",
          NSStringFromCGRect(path.bounds));
    NSLog(@"path.CGPath box before transform:%@",
          NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath)));

    [path applyTransform:CGAffineTransformMakeScale(2, 2)];

    NSLog(@"path.bounds box after transform:%@",
          NSStringFromCGRect(path.bounds));
    NSLog(@"path.CGPath box after transform:%@",
          NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath)));

    return 0;        
}

输出:

path.bounds box before transform:{{0, 0}, {1, 1}}
path.CGPath box before transform:{{0, 0}, {1, 1}}
path.bounds box after transform:{{0, 0}, {2, 2}}
path.CGPath box after transform:{{0, 0}, {1, 1}}

为什么?

4

2 回答 2

7

从 iOS 5.1 开始,当应用了新的转换时,CGPathUIBezier' 返回的.CGPath属性确实会更新。UIBezierPath

但是,这并不排除旧 iOS 版本的解决方案。您可以CGPath从中获取UIBezierPath,直接对其进行转换,然后将其设置回UIBezierPath. 瞧,所有其他属性,如边界和原点,将立即正确更新。

UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(0.0f, 0.0f,
                                                                 1.0f, 1.0f)];

CGAffineTransform transform = CGAffineTransformMakeScale(2.0f, 2.0f);
CGPathRef intermediatePath = CGPathCreateCopyByTransformingPath(path.CGPath,
                                                                &transform);

path.CGPath = intermediatePath;

CGPathRelease(intermediatePath);
于 2012-07-25T02:53:23.607 回答
4

造成这种差异的原因是因为对 applyTransform 的调用只是将变换矩阵存储在路径对象中。它不会导致路径本身被修改。path.bounds 是使用转换派生的计算属性,而调用 CGPathGetBoundingBox 只是迭代传入的 CGPath 对象的元素。

因为可能存在大量路径元素,所以存储变换矩阵,而不是在每次分配新矩阵时修改所有路径元素,作为优化完成。当仅查询 UIBezierPath 的某些属性(例如边界)时,此工作仅执行一次或最少执行一次。

于 2011-10-31T07:28:39.797 回答