So I'm trying to cut a circle out of an existing layer; and here's my code:
CGRect bounds = _containerLayer.bounds;
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.fillColor = [UIColor blackColor].CGColor;
CGFloat smallCircleRadius = (frame.size.width - barWidth)/2;
CGRect smallCircleRect = CGRectMake(CGRectGetMidX(bounds) - smallCircleRadius, CGRectGetMidY(bounds) - smallCircleRadius, 2 * smallCircleRadius, 2 * smallCircleRadius);
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:smallCircleRect];
[circlePath appendPath:[UIBezierPath bezierPathWithRect:bounds]];
maskLayer.path = circlePath.CGPath;
maskLayer.fillRule = kCAFillRuleEvenOdd;
_containerLayer.mask = maskLayer;
This code does work, as I now see a black rectangle with a hollow circle in the middle. But the problem is that when I tried to set maskLayer.fillColor = [UIColor clearColor].CGColor;, The whole thing including _containerLayer just disappears - I want to make the fillColor transparent so I can see what's originally in the _containerLayer (which wasn't cut out). What should I do to achieve this? Thanks!
Related
UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:80 startAngle:0 endAngle:(2 * M_PI) clockwise:YES];
CAShapeLayer * layer = [CAShapeLayer new];
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor clearColor].CGColor;
layer.lineWidth = 10;
layer.strokeEnd = 1;
layer.position = self.view.center;
layer.lineCap = kCALineCapRound;
[layer setPath : path.CGPath];
[self.view.layer addSublayer : layer];
CAGradientLayer * gradientLayer = [CAGradientLayer layer];
gradientLayer.startPoint = CGPointMake(0.0,0.5);
gradientLayer.endPoint = CGPointMake(1.0,0.5);
gradientLayer.frame = self.view.frame;
NSArray *colors = #[(id)[UIColor greenColor].CGColor,(id)[UIColor blueColor].CGColor,(id)[UIColor yellowColor].CGColor];
gradientLayer.colors = colors;
[gradientLayer setMask : layer];
[self.view.layer addSublayer : gradientLayer];
What Im doing:
Adding CAShapeLayer to view.layer with a path to draw a circle.
Adding CAGradientLayer ( 3 colors ) to view.layer and setingMask to the CAShapeLayer.
Result: with and without mask
The problem :
If I change the frame of the gradient to be on top of the circle ( because I want to see the all the colors on the circle ) its moves the circle as well.
particularly the change to the x and y of the gradient
So instead of
gradientLayer.frame = self.view.frame;
I change the x and y only ( width and hight doesn't causing this problem as far as I checked )
gradientLayer.frame = CGRectMake(100,100, self.view.frame.size.width, self.view.frame.size.height);
And this is the result
Can anyone explain why this is happening and what are the possible solutions ?
What Im trying to achieve is this
And then masking it with the CAShapeLayer but then this problem happens
Thanks in advance
change the shapelayer position, because gradient layer is fullscreen and shapelayer set center position and after you change the frame of gradient layer shapelayer also change with same position.
layer.position = CGPointMake(30, 250);
I used this to round top two corners of my UITextFeild
CAShapeLayer * maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: self.emailFeild.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath;
I also have border added to this UITextField as
self.emailFeild.layer.borderColor = [[self colorFromHexString:#"0x3263A3"]CGColor];
self.emailFeild.layer.borderWidth = 1.0f;
self.emailFeild.layer.mask = maskLayer;
but when I run it. It did not round the corners of border and I get this result
The mask layer doesn't get drawn, just used to compute the mask. Try:
-(void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius
{
CGRect bounds = self.bounds;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
byRoundingCorners:corners
cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
CAShapeLayer* frameLayer = [CAShapeLayer layer];
frameLayer.frame = bounds;
frameLayer.path = maskPath.CGPath;
frameLayer.strokeColor = [UIColor redColor].CGColor;
frameLayer.fillColor = nil;
[self.layer addSublayer:frameLayer];
}
-(void)roundTopCornersRadius:(CGFloat)radius
{
[self roundCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) radius:radius];
}
I want to create a mask layer which is a circle that makes the circle content transparent and keep everything around. Unfortunately, the following code does the opposite, it draws a circle and make everything around transparent.
CAShapeLayer * shape = [CAShapeLayer layer];
shape.frame = CGRectMake((CGSSize().width/2.f)-40.f, -40.f, 80.f, 80.f);
CGPathRef pathRef =
CGPathCreateWithEllipseInRect(CGRectMakeBoundsWithSize(shape.frame.size), NULL);
shape.path = pathRef;
shape.fillColor = [UIColor blueColor].CGColor;
self.layer.mask = shape;
Yeah, kCAFillRuleEvenOdd didn't do it's magic without adding a rect first, here is a working snippet though:
CAShapeLayer *shape = [CAShapeLayer layer];
shape.frame = self.bounds;
CGMutablePathRef pathRef = CGPathCreateMutable();
CGPathAddRect(pathRef, NULL, self.bounds);
CGPathAddEllipseInRect(pathRef, NULL, self.bounds);
shape.fillRule = kCAFillRuleEvenOdd;
shape.path = pathRef;
self.layer.mask = shape;
I am trying to draw a view with few hollow circles in it. The view background color will be black with opacity 0.5 and hollow circles on places where I could see the view underneath it. This is working fine with below piece of code but has an issue when my hollow circles intersects, I want to cover both of them as hollow area but due to even odd rule this is not working out. Any suggestions?
Or any alternatives?
- (void)addShadowView {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) cornerRadius:0];
for (NSValue *point in self.hollowFrames) {
UIBezierPath *circlePath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(point.CGPointValue.x - self.hollowCircleRadius.floatValue, point.CGPointValue.y - self.hollowCircleRadius.floatValue, 2.0 * self.hollowCircleRadius.floatValue, 2.0 * self.hollowCircleRadius.floatValue) cornerRadius:self.hollowCircleRadius.floatValue];
[path appendPath:circlePath];
}
[path setUsesEvenOddFillRule:YES];
CAShapeLayer *fillLayer = [CAShapeLayer layer];
fillLayer.path = path.CGPath;
fillLayer.fillRule = kCAFillRuleEvenOdd;
fillLayer.fillColor = [UIColor blackColor].CGColor;
fillLayer.opacity = 0.5;
[self.layer addSublayer:fillLayer];
}
This is how it looks right now. I want the intersected area also to be hollow and not filled with the fillColor.
don't fill the circles, clip out the centers.
I am trying to add rounded corners to only the top corners of my UITableView but the problem is, with the code below, it just makes a black layer over my whole UITableView. How would I fix this?
//Rounded Corners for top corners of UITableView
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:thetableView.bounds
byRoundingCorners:UIRectCornerTopLeft
cornerRadii:CGSizeMake(10.0, 10.0)];
UIBezierPath *maskPath2 = [UIBezierPath bezierPathWithRoundedRect:thetableView.bounds
byRoundingCorners:UIRectCornerTopRight
cornerRadii:CGSizeMake(10.0, 10.0)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = thetableView.bounds;
maskLayer.path = maskPath.CGPath;
CAShapeLayer *maskLayer2 = [CAShapeLayer layer];
maskLayer.frame = thetableView.bounds;
maskLayer.path = maskPath2.CGPath;
// Set the newly created shape layer as the mask for the image view's layer
[thetableView.layer addSublayer:maskLayer];
[thetableView.layer addSublayer:maskLayer2];
the following code works for me for a navigationbar, just change the first line and put your self.tableView:
CALayer *capa = [self.navigationController navigationBar].layer;
[capa setShadowColor: [[UIColor blackColor] CGColor]];
[capa setShadowOpacity:0.85f];
[capa setShadowOffset: CGSizeMake(0.0f, 1.5f)];
[capa setShadowRadius:2.0f];
[capa setShouldRasterize:YES];
//Round
CGRect bounds = capa.bounds;
bounds.size.height += 10.0f; //I'm reserving enough room for the shadow
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
[capa addSublayer:maskLayer];
capa.mask = maskLayer;
I think the best way to make a background view for the table view which view has rounded top corner.Its just a solution to solve the problem.May be it will help you.