对 UIBezierPath 感到困惑 +应用变换 + CG路径

发布于 2024-12-06 04:09:19 字数 1124 浏览 1 评论 0原文

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

为什么?

I scale UIBezierPath (built of one [0,0 - 1x1] rect) by factor 2 in both x and y directions. UIBezierPath ".bounds" is alright (i.e. scaled as expected), while ".CGPath" remains unchanged...

Code:

#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;        
}

Output:

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}}

Why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人心善变 2024-12-13 04:09:19

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

不过,这并不排除针对旧版 iOS 版本的解决方案。您可以从UIBezierPath获取CGPath,直接转换它,然后将其设置回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);

As of iOS 5.1, the CGPath returned from UIBezier's .CGPath property is indeed updated when the UIBezierPath has a new transform applied.

However, this doesn't preclude a solution for older iOS versions. You can get the CGPath from the UIBezierPath, transform it directly, then set it back onto the UIBezierPath. Lo and behold, all the other properties, like bounds and origins, will update correctly and immediately.

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);
深白境迁sunset 2024-12-13 04:09:19

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

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

The reason for this difference is because the call to applyTransform simply stores the transform matrix in the path object. It does not cause the path itself to be modified. path.bounds is a calculated property that is derived using the transform, whereas the call the CGPathGetBoundingBox is simply iterating over the elements of the passed in CGPath object.

Because there could potentially be a great number of path elements, storing the transform matrix, and not modifying all of the the path elements every time a new matrix is assigned, is done as an optimization. This work is only done once, or minimally, when only certain properties, such as the bounds, of the UIBezierPath are queried.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文