对 UIBezierPath 感到困惑 +应用变换 + CG路径
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从 iOS 5.1 开始,当
UIBezierPath
已更新时,从UIBezier
的.CGPath
属性返回的CGPath
确实会更新。应用了新的变换。不过,这并不排除针对旧版 iOS 版本的解决方案。您可以从
UIBezierPath
获取CGPath
,直接转换它,然后将其设置回UIBezierPath
。你瞧,所有其他属性,如边界和原点,都将立即正确更新。As of iOS 5.1, the
CGPath
returned fromUIBezier
's.CGPath
property is indeed updated when theUIBezierPath
has a new transform applied.However, this doesn't preclude a solution for older iOS versions. You can get the
CGPath
from theUIBezierPath
, transform it directly, then set it back onto theUIBezierPath
. Lo and behold, all the other properties, like bounds and origins, will update correctly and immediately.造成这种差异的原因是因为对 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.