iOS:UIBezierPath和CAShapeLayer fillRule

时间:2013-10-15 18:06:29

标签: 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错误,我想知道是否有其他方法可以实现此目的。提前致谢。

1 个答案:

答案 0 :(得分:7)

主要问题是你无法真正填充形状的外部,因为没有通用的方法来定义它的含义。您需要做的是首先在您的形状的“外部”周围绘制一条路径,然后将该圆圈添加为子路径。如何执行此操作取决于您要使用的填充规则。 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有一些很好的图表,我觉得它很有用。

相关问题