2013-10-15 3 views
2

Я использовал оба UIBezierPath и CAShapeLayer раньше. Но почти каждый раз в сочетании с заполнением объекта, содержащегося внутри пути, с цветом внутри. Но я хотел бы, чтобы на этот раз заполнить цвет вне объекта, содержащегося в UIBezierPath.iOS: UIBezierPath и CAShapeLayer fillRule

Я просто написал и побежал следующий простой код, пытаясь заставить себя ознакомиться с 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 здесь неправильно, я хотел бы знать, есть ли другие методы, которые могут это сделать. Заранее спасибо.

ответ

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 есть хорошие диаграммы, которые я нахожу полезными.

+0

Привет, эй, ты действительно хорош в этом. +1. Благодарю. Ради полноты, возможно ли это с помощью 'CGMutablePath'? Заранее спасибо. – Unheilig

+0

Тем не менее, я бы назвал этот ответ первым. Надеюсь, вы могли бы подробнее рассказать о 'CGMutablePath' с этим. – Unheilig

+1

Да, эта же основная идея применима для 'CGPath' с использованием CGPathAddArc и т. Д. – frozendevil

Смежные вопросы