对UIBezierPath + applyTransform + CGPath感到困惑

时间:2011-09-25 11:58:13

标签: ios core-graphics cgpath uibezierpath

我在x和y方向上按比例2缩放UIBezierPath(由一个[0,0 - 1x1] rect构建)。 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}}

为什么?

2 个答案:

答案 0 :(得分:7)

从iOS 5.1开始,当CGPath应用了新的转换时,UIBezier的{​​{1}}属性返回的.CGPath确实已更新。

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

UIBezierPath

答案 1 :(得分:4)

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

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