iOS:UIBezierPath 和 CAShapeLayer 填充规则

标签 ios uibezierpath cashapelayer

我以前用过UIBezierPathCAShapeLayer。但几乎每次都结合用内部颜色填充路径中包含的对象。但这次我想在 UIBezierPath 包含的对象之外填充颜色。

我刚刚编写并运行了以下简单代码,试图让自己熟悉 fillRule 属性:

CAShapeLayer *myLayer = (CAShapeLayer *) self.layer; //size: 320 X 480
UIBezierPath *testPath = [UIBezierPath bezierPathWithOvalInRect:(CGRect){{100, 100}, 100, 100}]; //a simple circle
myLayer.fillRule = kCAFillRuleNonZero; // have tried this as well: kCAFillRuleEvenOdd;
myLayer.path = testPath.CGPath;
myLayer.fillColor = [UIColor whiteColor].CGColor;

但颜色仍然在内部填充。我想知道的是,如何在路径外填充颜色?如果我在这里使用了错误的fillRule,我想知道是否有其他方法可以实现这一点。提前致谢。

最佳答案

主要问题是您无法真正填充形状的外部,因为没有定义其含义的通用方法。您需要做的是首先围绕形状的“外部”绘制一条路径,然后将圆添加为子路径。如何操作取决于您要使用的填充规则。 EvenOdd 是最简单的:

CAShapeLayer *myLayer = (CAShapeLayer *) self.layer;
UIBezierPath *testPath = [UIBezierPath bezierPathWithRect:self.bounds];
[testPath appendPath:[UIBezierPath bezierPathWithOvalInRect:(CGRect){{100, 100}, 100, 100}]];
myLayer.fillRule = kCAFillRuleEvenOdd;
myLayer.path = testPath.CGPath;
myLayer.fillColor = [UIColor whiteColor].CGColor;

NonZero 有点难,因为您必须强制路径为逆时针方向,这对于大多数 UIBezierPath 便捷方法来说不是一个选项:

CAShapeLayer *myLayer = (CAShapeLayer *) self.layer;
UIBezierPath *testPath = [UIBezierPath bezierPathWithRect:self.bounds];
UIBezierPath *counterClockwise = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI clockwise:NO];
[counterClockwise appendPath:[UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:M_PI endAngle:0 clockwise:NO]];
[testPath appendPath:counterClockwise];
myLayer.fillRule = kCAFillRuleNonZero;
myLayer.path = testPath.CGPath;
myLayer.fillColor = [UIColor redColor].CGColor;

根据您构建实际路径的方式,这两种方式可能都没有什么不同。

如果您还没有看到,winding rules documentation有一些我觉得很有帮助的漂亮图表。

关于iOS:UIBezierPath 和 CAShapeLayer 填充规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19388061/

相关文章:

ios - 将 UIBezierPath 转换为字符串

ios - 如何将 TapGestureRecogniser 分配给用户绘制的线条

swift - 在 CAShapeLayer 中对不同角进行动画处理

ios - 如何使用 CKSubscription 检查 CKAsset 的变化?

ios - 在 Swift 中对 Big Int 值进行排序

swift - 从贝塞尔路径计算点

swift - CAShapeLayer 获取当前比例

ios - 使用 CAShapeLayer 和 UIBezierPath 剪辑屏蔽 uiview

ios - xcodebuild 不启动 iOS 7.0 模拟器

iphone - 有没有办法捕获或处理 EXC_BAD_ACCESS?