How to create a WaterDrop Shape with UIBezierPath - ios

I write some code for creating the below with UIBezierPath but it didn't work. Can someone help me what's wrong with my code.
but i was tried with drawRect: it works fine....My problem is same i need in UIBezierPath as,
+ (UIBezierPath *)DropShape:(CGRect)Frame {}
my code using drawRect: is
CGContextRef context = UIGraphicsGetCurrentContext();
CGGradientRef gradient;
CGColorSpaceRef colorspace;
CGFloat locations[3] = { 0.0, 0.5, 1.0 };
NSArray *colors = #[(id)[UIColor redColor].CGColor];
colorspace = CGColorSpaceCreateDeviceRGB();
gradient = CGGradientCreateWithColors(colorspace,
(CFArrayRef)colors, locations);
CGPoint startPoint, endPoint;
CGFloat startRadius, endRadius;
startPoint.x = self.frame.size.width/2;
startPoint.y = 30;
endPoint.x = 175;
endPoint.y = 175;
startRadius = 0;
endRadius = 75;
CGContextDrawRadialGradient(context, gradient, startPoint,
startRadius, endPoint, endRadius, 0);
Thanks in advance...

There is an app called PaintCode which you can try for free.
You can draw onto a canvas and it will produce the drawRect code that you can copy and paste into your app.
I don't think you can copy from the trial version but it will create the path which you can type into your code manually.
It's worth a look.

Related

IOS app different when loading via TestFlight

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);

Black to White radial gradient is giving whole black screen

It should be very simple to create a black to white radial gradient using Core Graphics, but even after many tries I am not able to figure where I am going wrong.
I want something like this:
This is my code:
CGFloat radius = shapeRect.size.width/2.0;
CGPoint center = CGPointMake(shapeRect.origin.x+shapeRect.size.width/2, shapeRect.origin.y+shapeRect.size.height/2);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate(NULL, shapeRect.size.width, shapeRect.size.height, 8, shapeRect.size.width*4, colorSpace, kCGImageAlphaNone);
CGFloat components[] = {0.0, 1.0};
CGFloat locations[] = {0.0, 1.0};
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);
CGContextDrawRadialGradient(context, gradient, center, 10, center, radius, 0);
CGImageRef img = CGBitmapContextCreateImage(context);
[maskedView setImage:[UIImage imageWithCGImage:img]];
CGGradientRelease(gradient);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
ShapeRect here has self.view bounds.
I am getting a whole black screen with no gradient as output.
I am using iPhone 7 simulator.
Your suggestions can save my day
Thank you.
Please check this snippet. You can change components and locations values to get what you want and to understand how the drawing works. Refer to CGGradientCreateWithColorComponentsdescription
#import "TestView.h"
#implementation TestView {
CGGradientRef _gradient;
}
-(void)drawRect:(CGRect)rect
{
CGFloat radius = self.frame.size.width / 2.0;
CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
CGContextRef context = UIGraphicsGetCurrentContext();
CGGradientRef gradient = [self createGradient];
CGContextDrawRadialGradient(context, gradient, center, 10, center, radius, kCGGradientDrawsBeforeStartLocation);
}
-(CGGradientRef)createGradient
{
if (!_gradient) {
CGFloat components[] = { 0.0, 1.0, 0.5, 0.5, 1.0, 0.3 };
CGFloat locations[] = { 0.0, 0.6, 1.0 };
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
_gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 3);
CGColorSpaceRelease(colorSpace);
}
return _gradient;
}
- (void)layoutSubviews
{
self.backgroundColor = [UIColor whiteColor];
self.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.layer.borderWidth = 1.;
}
#end
Result:

Drawing Circular Gradient

I would like to draw a circular gradient like in the example picture below. I can manage a radial gradient easily but I am not sure how to do a circular one.
I was thinking of drawing a gradient on a line and then transforming it to a circle. Would that be possible?
This is how I draw the radial gradient:
CGFloat a = MIN(self.frame.size.width, self.frame.size.height) - _lineWidth;
//Get current context
CGContextRef mainContext = UIGraphicsGetCurrentContext();
CGRect newRect = rect;
newRect.origin.x = ((self.frame.size.width - a)/2.0f);
newRect.origin.y = ((self.frame.size.height - a)/2.0f);
newRect.size.width = a;
newRect.size.height = a;
// Fill circle
const CGFloat *_components = CGColorGetComponents(_fillColor.CGColor);
CGFloat red = _components[0];
CGFloat green = _components[1];
CGFloat blue = _components[2];
CGFloat alpha = _components[3];
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
CGFloat redBallColors[] = {
red,green,blue,0.5,
red,green,blue,alpha,
};
CGFloat glossLocations[] = {0.0, 1.0};
CGGradientRef ballGradient = CGGradientCreateWithColorComponents(baseSpace, redBallColors, glossLocations, 2);
CGPoint startPoint = self.center;
CGPoint endPoint = self.center;
CGContextDrawRadialGradient(mainContext, ballGradient, startPoint, 0, endPoint, a/2, 0);
Thanks a lot!

Quartz2d gradient fill an oval

I have a simple drawing routine that allows the user to draw two enclosed ovals on the screen. I want to fill the ovals with a gradient, using the inner oval to represent the "percentage" of the gradient. i.e. Th gradient will smoothly transition between the outside oval to the inside oval.
I have the interactive drawing working fine, now I just need to fill with the gradient.
Any thoughts? The docs only talk about perfectly circular gradients, not ovals.
_mike
I do not know whether it is possible oval gradient . But you can transform circle to oval. The idea is to draw a circle in transformed coordinate system.
Sample of code:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextScaleCTM(context, 1.0, 0.5);
CGGradientRef gradient;
CGColorSpaceRef colorspace;
CGFloat locations[2] = { 0.0, 1.0};
NSArray *colors = #[(id)[UIColor whiteColor].CGColor, (id)[UIColor blueColor].CGColor];
colorspace = CGColorSpaceCreateDeviceRGB();
gradient = CGGradientCreateWithColors(colorspace, (CFArrayRef)colors, locations);
CGPoint startPoint, endPoint;
CGFloat startRadius, endRadius;
startPoint.x = 180;
startPoint.y = 180;
endPoint.x = 180;
endPoint.y = 180;
startRadius = 0;
endRadius = 100;
CGContextDrawRadialGradient (context, gradient, startPoint, startRadius, endPoint, endRadius, 0);
CGContextRestoreGState(context);
}
Result of running code:

NSString drawAtPoint: and kCGTextFillClip, why doesn't it work?

I am facing a problem with NSString method drawAtPoint and kCGTextFillClip. I needed to create a UILabel with a gradient instead of a simple color, so I've subclassed it and overrode the drawRect method. I managed to get what I wanted by using the function CGContextShowTextAtPoint, but it doesn't handle UTF-8 properly, which is essential to me.
I am aware that this is a common problem so after searching for a bit, I found out that I could use drawAtPoint to solve this encoding problem. Indeed, the text is now showing properly. The problem is I don't know how to make kCGTextFillClip work anymore.
Look at the result.
As you can see, it seems to clip to the first letter just fine, but not after that. Do you have any idea on how to solve this issue?
Here's the code I'm using :
- (void)drawRect:(CGRect)rect {
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGRect viewBounds = self.bounds;
CGContextSaveGState(theContext);
CGContextTranslateCTM(theContext, 0.0, viewBounds.size.height/2 + 1);
CGContextSetTextDrawingMode(theContext, kCGTextFillClip);
[self.text drawAtPoint:CGPointMake(0, 0) withFont:[UIFont fontWithName:#"Helvetica-Bold" size:11.5]];
// Creation of the gradient
CGFloat locations[2] = { 0.0f, 1.0f };
CGFloat components[8] = {
190.0/255, 190.0/255, 190.0/255, 1.0, // Start color
113.0/255, 113.0/255, 113.0/255, 1.0 // End color
};
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, 2);
CGPoint topCenter = CGPointMake(CGRectGetMidX(viewBounds), 0.0f);
CGPoint midCenter = CGPointMake(CGRectGetMidX(viewBounds), CGRectGetMidY(viewBounds));
CGContextDrawLinearGradient(theContext, gradient, topCenter, midCenter, 0);
Thank you!
Try and draw letter by letter?

Resources