My goal is
1. add gradient for my view (done)
2. add drop shadow for the bottom edge of my view ( issue at here )
What I am doing is :
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *whiteColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
UIColor *lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0];
CGRect paperRect = self.bounds;
// Fill with gradient
[self drawLinearGradient:context for:paperRect start:whiteColor.CGColor end:lightGrayColor.CGColor];
CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
CGContextSetLineWidth(context, .9);
CGContextStrokeRect(context, paperRect);
// Add shadow
CGContextSetShadowWithColor(context, CGSizeMake(0, self.frame.size.height), 9.0, [UIColor blueColor].CGColor);
}
-(void)drawLinearGradient:(CGContextRef)context for:(CGRect)rect start:(CGColorRef)startColor end:(CGColorRef)endColor {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
However, what I am getting is the picture below without shadow at all
Am I on the right track but missing something in the middle ? Please help if you have any ideas..
You need to set the shadow properties before drawing whatever it is that's supposed to have the shadow. Put your call to CGContextSetShadowWithColor before the call to CGContextStrokeRect.
Also, the offset should probably not be as large as you're making it. The shadow offset controls how much the shadow is offset from the pixels that were drawn with that shadow, so unless you want the shadow to actually start very far away from your rect you probably want an offset of just a pixel or so, like CGSizeMake(0.0, 1.0).
Related
I have a view in storyboard controller which extends my custom UIView and when I try to draw a gradient in drawRect it displays fine when loading on to device/sim via XCode but when I install via TestFlight after uploading to ITunes Connect the gradient isn't present at first (displays black background) - it needs a rotation of the device and the gradient displays fine again. What could be causing this behaviour?
- (void)drawRect:(CGRect)rect {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
NSArray *gradientColors = [NSArray arrayWithObjects:
(id)[[self colorWithHexString:#"FF7542"]CGColor],
(id)[[self colorWithHexString:#"FF7542"]CGColor],
(id)[[self colorWithHexString:#"FFC0A1"]CGColor],
nil];
CGFloat gradientLocations[] = {0, 1};
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) gradientColors, gradientLocations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor : BLACK_SHADOW];
[shadow setShadowOffset : CGSizeMake (1.0, 1.0)];
}
I solved this by creating my gradient another way and strangely it shows first time when loaded without the need for a rotation.
CGContextRef current_context = UIGraphicsGetCurrentContext();
CGContextSaveGState(current_context);
// Gradient
CGFloat locations[2] = {0.0, 1.0};
CGFloat components[8] = {1.00,0.75,0.63,1.0,1.00,0.46,0.26,1.0};
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 2);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextDrawLinearGradient(current_context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorspace);
Hi I have draw a gradient in core graphic using drawRect function..
but I don't know how to draw a border to surround this view?
this is my code, could anyone help?
- (void)drawRect:(CGRect)rect {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
NSArray *gradientColors = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor, [UIColor colorWithRed:90/255.0 green:0 blue:0 alpha:1].CGColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) gradientColors, NULL);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
If you just want to draw a border around the view, try this:
UIBezierPath *border = [UIBezierPath bezierPathWithRect:rect];
[[UIColor redColor] setStroke];
[border setLineWidth:4.0];
[border stroke];
Use it at the end of drawRect: method.
I drew a line using drawRect. Now I want to change the color of it.
Example Code: self.pattern.backgroundColor = [UIColor clearColor];
I need to be able to change the color of the drawRect like that code. I get stuck on the second part of the code.
self. ? . backgroundColor: The questions marks is where i get stuck. What should I put there for a drawRect?
Here is some code from my drawRect too:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// Setup background
//CGFloat components1[] = {0.0, 0.0, 0.0, 1.0};
//CGColorSpaceRef colorspace1 = CGColorSpaceCreateDeviceRGB();
////CGColorRef black = CGColorCreate(colorspace1, components1);
//CGContextSetFillColorWithColor(context,black);
//CGContextSetRGBFillColor(context,0.0,0.0,0.0,1.0);
// 1 pixel: iphone 6 the point = 0.5 and 6 plus = 0.333333;
//CGFloat point =1.f/[UIScreen mainScreen].scale;
CGFloat point =width/[UIScreen mainScreen].scale;
CGContextSetLineWidth(context,point);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat red [] = {1.0, 0.0, 0.0, 1.0}; // green
CGFloat green [] = {0.0, 1.0, 0.0, 1.0}; // green
CGColorRef color = CGColorCreate(colorspace, green);
CGContextBeginPath(context);
if(bFirstLine && bAlter)
{
CGColorRef colorR = CGColorCreate(colorspace, red);
CGContextSetStrokeColorWithColor(context, colorR);
}
}
[[UIColor redColor] setFill]; // to set the color for fillings
[[UIColor redColor] setStroke]; // to set the color for strokes
and in your case (if i got you right):
[self.backgroundColor setFill];
[self.backgroundColor setStroke];
I want to draw the Circular progress view with gradient as image :
Design Image
I tried the below code but the result color is not correct. This is my code:
//draw gradient
CGFloat colors [] = {
1.0, 0.7,
0.2, 0.4
};
CGFloat locations[] = { 0.0, 1.0 };
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceGray(); // gray colors want gray color space
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, locations, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;
CGContextSaveGState(context);
CGContextAddPath(context, progressPath);
CGContextClip(context);
CGRect boundingBox = CGPathGetBoundingBox(progressPath);
CGPoint gradientStart = CGPointMake(0.0, CGRectGetMinY(boundingBox));
CGPoint gradientEnd = CGPointMake(1.0, CGRectGetMaxY(boundingBox));
CGContextDrawLinearGradient(context, gradient, gradientStart, gradientEnd, 0);
CGGradientRelease(gradient), gradient = NULL;
CGContextRestoreGState(context);
The progressPath is the progress line with color :
[UIColor colorWithRed:21/255.0f green:182/255.0f blue:217/255.0f alpha:1.0]
UPDATE:
This is an image my code produced: Result Image
The result image is not the same the design, the color is not the same. I dont know why.
Please help me to correct this. Thanks in advance.
The kind of gradient you are looking for, where the color varies as a function of the angle around a center point, is called an angle gradient. Unfortunately, iOS does not have a built-in way to draw angle gradients, but you can do it using an open-source library such as paiv/AngleGradientLayer.
Working code:
- (void) setGradientWithFrame:(CGRect)frame
{
//create the gradient
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = frame;
//this example is white-black gradient, change it to the color you want..
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor blackColor] CGColor], nil];
gradient.cornerRadius = frame.size.height/2.0f;
[self.view.layer insertSublayer:gradient atIndex:0];
CALayer *whiteCircle = [CALayer layer];
whiteCircle.frame = CGRectMake(frame.origin.x + 10, frame.origin.y + 10, frame.size.width - 20, frame.size.height - 20);
whiteCircle.backgroundColor = [[UIColor whiteColor] CGColor];
whiteCircle.cornerRadius = whiteCircle.frame.size.width/2.0f;
[self.view.layer insertSublayer:whiteCircle atIndex:1];
CALayer *whitesquare = [CALayer layer];
whitesquare.frame = CGRectMake(50, frame.size.height - 20, 25, 25);
whitesquare.backgroundColor = [[UIColor whiteColor] CGColor];
whitesquare.transform = CATransform3DMakeRotation(-20.0 / 180.0 * M_PI, 0.0, 0.0, 1.0);
[self.view.layer insertSublayer:whitesquare atIndex:2];
}
to call the method:
[self setGradientWithFrame:CGRectMake(0, 0, 100, 100)];
PS. change the color to the color of gradient to the color you want:
I have a camera app to load photo into a device with mask. Everything is OK. When I try to use renderInContext to save the view to an image, I only see the image without any mask.
UIGraphicsBeginImageContext(contentView.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[contentView.layer renderInContext:context];
UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(outImage, self, #selector(image: didFinishSavingWithError: contextInfo:), context);
I have read some paper from Apple to say that renderInContext don't support mask and composition. I've made some search on the internet to get the information that UIView needed to draw as a context first and then use renderInContext to save the image.
Now my question is what method to do the job? What about drawRect, drawInRect, drawLayer, drawInContent, or other method. Can anyone give me a hint. Thanks a lots.
I started from here: http://chinkisingh.com/2013/03/03/draw-on-iphoneipad-screen-using-bezier-paths-core-graphics-ios-app-development/
I have a UIBezierPath and I wanted to apply a gradient to it and apply to an existing image, see if the following code helps
CGRect r = CGRectMake(0, 0, HEART_SIZE, HEART_SIZE);
UIBezierPath *heart = [Bezier heartShape:r]; //this is only in my case
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIColor *darkPink = [UIColor colorWithHue:0.915 saturation:1.000 brightness:0.941 alpha:1.000];
UIColor *lightPink = [UIColor colorWithHue:0.917 saturation:0.647 brightness:1.000 alpha:1.000];
NSArray *gradientColors = [NSArray arrayWithObjects:
(id)darkPink.CGColor,
(id)lightPink.CGColor,
(id)darkPink.CGColor, nil];
CGFloat gradientLocations[] = {0, 0.5, 1};
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations);
CGColorSpaceRelease(colorSpace);
UIGraphicsBeginImageContext(r.size);
heart.lineCapStyle = kCGLineCapRound;
heart.lineWidth = 10.0f;
[[UIColor blackColor] setStroke];
[[UIColor redColor] setFill];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
[heart stroke]; //removed the black stroke around
[heart fill];
CGContextAddPath(context, heart.CGPath);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, CGPointMake(10, 10), CGPointMake(210, 210), kCGGradientDrawsAfterEndLocation); //check that gradient is drawn in the right place
CGGradientRelease(gradient);
UIImage *theRightImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();