I'm using this code in my UIView subclass to draw a circle with a gradient fill:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadow (context, CGSizeMake(4,4), 5);
CGContextBeginPath (context);
CGContextAddEllipseInRect(context, CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 38, 38));
CGContextClosePath (context);
CGContextClip (context);
CGContextDrawLinearGradient(context, gradient, CGPointMake(CGRectGetMinX(self.bounds), CGRectGetMaxX(self.bounds)), CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMinY(self.bounds)), 0);
}
The circle and the gradient draw fine, but I see no shadow. I'm not sure why its not working, because I used the same CGContextSetShadow function in a different view subclass and it worked fine.
NOTE: In the above code, "gradient" is an ivar that was defined previously.
A gradient draw doesn't count as a fill; only fills and strokes get shadows. (You may want to report this as a bug.)
As a workaround, fill the path (with solid black), then turn off the shadow, then draw the gradient.
Related
I'm drawing to a CGContext and using a CGImageRef-based mask:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToMask(context, rect, _firstMaskImageRef);
CGContextSetFillColorWithColor(context, color);
CGContextFillRect(context, rect);
I have a second mask that I then want to switch to:
CGContextClipToMask(context, rect, _secondMaskImageRef);
CGContextSetFillColorWithColor(context, color); // color has changed FWIW
CGContextFillRect(context, rect); // as has rect
But, this intersects the two masks instead of replacing the first.
How do you (if you can) clear out or reset the clipping mask for a CGContext?
You can save the graphics state before you set the clipping mask, and then reset it afterwards, like this:
CGContextSaveGState (context);
...Set your first clipping mask, fill it, etc.
CGContextRestoreGState (context);
...Do other stuff
To reset the clipping mask, use:
CGContextResetClip(context);
Later versions of Swift (3+?) use the following syntax instead:
context.saveGState()
// set your clipping mask, etc.
context.restoreGState()
// everything's back to normal
I have a shadow image that I would like to draw around the outer edge of a grouped UITableView section. This is the image:
I can get the UIBezierPath that represents the rect I want to draw around, but I can't figure out how to repeat the image along the route of the rect. So far it just fills the rect with the image:
UIImage *patternImg = [UIImage imageNamed:#"cellShadow"];
UIColor *fill = [UIColor colorWithPatternImage:patternImg];
[fill setFill];
CGRect aSectRect = [self rectForSection:0];
UIBezierPath *aSectPath = [self createRoundedPath:aSectRect];
[aSectPath fill];
Is this possible? What do I need to do?
Unfortunately, there's no way to have UIBezierPath use an image as a "brush" which is essentially what you'd want. But you can have CoreGraphics draw a shadow for you:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadow(context, CGSizeZero, myShadowRadius);
// Draw your shape here
Now if you draw just one shape it will get a shadow. But if you draw more shapes, each will get its own shadow which might not be what you want. The solution is called a transparency layer, which is not related to CALayers or something but is just some kind of "grouping" in CoreGraphics:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadow(context, CGSizeZero, myShadowRadius);
CGContextBeginTransparencyLayer(context, NULL);
// Draw your shapes here.
CGContextEndTransparencyLayer(context);
Between the CGContextBeginTransparencyLayer and CGContextEndTransparencyLayer calls the shadow is disabled. After the CGContextEndTransparencyLayer call, the shadow is applied to everything that has been drawn between begin and end as if it were just one shape.
I'm replacing the background view of a UITableViewCell with my own custom subclass of UIView, in which I override the drawRect method with my own, which creates a multi-colored and changing background.
The problem is that when the TableViewCell is selected, the graphics under are completely hidden and it looks odd. I need to create a custom selectedBackgroundView in order to fix this. The problem is that that view needs to create a blue gradient tint over the graphics already there, and I don't know how to draw a CGRect or something similar that is partially transparent.
// Write this In your - (void)drawRect:(CGRect)rect
// To draw semi transparent Square
// Create Current Context To Draw
CGContextRef context = UIGraphicsGetCurrentContext();
UIBezierPath *square = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)];
// following method will fill red color with alpha 0.4 last one in parameter list
// first 3 are Red, Green and Blue Respectively.
CGContextSetRGBFillColor(context, 1, 0, 0, 0.4);
[square fill];
[square stroke];
Here is my drawRect:
- (void)drawRect:(CGRect)rect
{
CGContextFillEllipseInRect(UIGraphicsGetCurrentContext(), self.bounds);
}
and the instances of this class are added a subviews the next way:
(#define DOTS_SIZE 30)
[self addSubview:[[VertexView alloc] initWithFrame:CGRectMake(anchor.x-DOTS_SIZE/2, anchor.y-DOTS_SIZE/2, DOTS_SIZE, DOTS_SIZE)]];
As far as I understand, I should get and ellipse (circle my case) in the views bounds. But I get it fully filled with rectangle (square).
By the way, I have logged bounds and their size is 30x30, so I should get nice little circles, but I get squares (T_T)
I'll be thankful for any advise!
The problem is that you have to make some setup before drawing the ellipse. For example:
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor); // Or any other color.
CGContextFillEllipseInRect(ctx, self.bounds);
}
And to make background transparent you can check out: Setting A CGContext Transparent Background
I'm drawing several circles within my view by means of the drawRect function.
I'd like to have my circles pop up (scale to 1.2 -> scale to 1.0)
I've used coreanimation in the past but using OpenGL takes different functions.
Here's a snippit of my code which draws a circle in my view:
//calling draw function
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//setting a specific fill color
CGContextSetRGBFillColor(contextRef, 0.0, 255.0, 0.0, 1.0);
//drawing the circle with a specific height, weight and x,y location
CGContextFillEllipseInRect(contextRef, CGRectMake(30 ,30, 20,20));
How can I animate this circle that it 'pops up'.
"Pops up" is not telling me that much.
if you want it to go from small to big modify width and height of rect.use a global int variable